В c доступ к первому элементу структуры с использованием адреса структуры и указателей - PullRequest
0 голосов
/ 16 января 2019

Я заметил, что адрес struct и адрес первого элемента выглядят одинаково. Поэтому я попытался получить доступ к первому элементу struct, используя адрес основного struct. Но я получаю сообщение об ошибке.

В совместимом типе аргумента 1 дисплея.

Какую ошибку я здесь делаю?

код

#include <stdio.h>
#include <stdlib.h>
#define BASE(class) *(&class)

struct animal {
    int walk;
    int hear;
};

struct bird {
    struct animal *base;
    int fly;
};

void display(struct animal *common) {
    printf("All animal details hear=%d  walk=%d ", common->hear, common->walk);
}

int main() {
    struct bird peacockptr;
    struct animal base;
    base.hear = 1;
    base.walk = 1;
    peacockptr.base = &base;

    struct bird *pecock = &peacockptr;
    pecock->fly = 1;

    printf("base address using peacock struct %d\n",
       BASE(peacockptr));  // both are printing same address
    printf("base address animal %d\n",
       &base);  // both are printing same address

    display(&base);     // here it work
    display(BASE(peacockptr));  // getting error
}

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Как уже упоминалось, вы можете удалить свой макрос BASE, так как операторы отменяют указатели.

Я немного уточнил и исправил твой код и объяснил, где ты ошибаешься:

#include <stdio.h>
#include <string.h>

struct animal
{
    int walk;
    int hear;
};

struct bird
{
    struct animal *base;
    int fly;
};

void display(struct animal *common)
{
    printf("All animal details hear=%d  walk=%d\n",common->hear, common->walk);
}

int main()
{
    struct bird peacock; // removed ptr suffix, since it is not a pointer
    struct animal base ;

    base.hear=1;
    base.walk=1;

    peacock.base= &base;

    struct bird *peacockptr = &peacock;
    peacockptr->fly=1;

    printf("base address using peacock struct %p\n",  (void *)*(struct animal **)peacockptr); //This is the address of base using peackockptr
    printf("base address animal %p\n", (void *)&base); //This is the address of base

    display(&base);
    display(*(struct animal **)peacockptr);

    return 0;
}

Обратите внимание, что адрес peackock равен адресу первого элемента структуры, который является struct animal *. Поэтому вам нужно привести peacockptr к struct animal ** (потому что он указывает на первый элемент типа struct animal *), а затем разыменовать его, чтобы получить адрес base.

0 голосов
/ 16 января 2019

Это правда, что адрес структуры совпадает с адресом ее первого члена. Тем не менее, они имеют различные типы . Один имеет тип struct animal *, а другой - struct base *.

В этом случае вам разрешено конвертировать между ними, однако для этого вам нужно явное приведение.

display((struct animal *)BASE(peacockptr));   

Также относительно того, как вы определили свой макрос BASE:

#define BASE(class) *(&class)

Операторы * и & взаимно отменяют друг друга, так что это, по сути, запрет. BASE(peacockptr) эквивалентно peacockptr.

Причина, по которой вам сейчас не удается выполнить приведение, состоит в том, что вы peacockptr определены как экземпляр и pecock как указатель , т.е. вы перепутали себя с наименование Переключите имена, чтобы отразить использование:

struct bird peacock;
struct animal base;
base.hear=1;
base.walk=1;
peacock.base= &base;

struct bird *peacockptr =&peacock;
peacockptr->fly=1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...