Внутренняя разница между структурой и массивом в C - PullRequest
1 голос
/ 26 августа 2011

каждый.

Вот тестовая программа, которую я написал.

#include <stdio.h>
#include <stdlib.h>

typedef struct _item {
    int value;
} item , *pItem;

typedef struct _itemcontainer {
    pItem i;
} itemcontainer, *pItemcontainer;

int main(void) {
    item i;
    i.value = 1;

    pItem pi = &i;
    pItem* ppi = &pi;

    itemcontainer ei = {&i};
    pItem* pei = (pItem*)(&ei);

    pItem api[1] = {&i};

    printf("First case: %d\n", (*ppi)->value);
    printf("Second case: %d\n", (*pei)->value);
    printf("Third case: %d\n", (*api)->value);


    return EXIT_SUCCESS;
}

Результаты трех функций printf совпадают, т. Е. 1 . Исходя из кода, инициализация переменной ei и api равна {& i} . Так что я думаю pItem * pei = (pItem *) ei должно работать, однако это не удалось. Может ли кто-нибудь сказать мне разницу между ei и api ? Похоже, это связано с тем, как компилятор работает со структурой и массивом, в чем я не очень хорош. Мне нужно конкретное объяснение. Заранее спасибо.

С наилучшими пожеланиями

Jfhu

1 Ответ

2 голосов
/ 26 августа 2011

Разница в том, что имя массива неявно преобразуется в указатель на его первый элемент в большинстве ситуаций, тогда как имя объекта типа структуры не является.

Выражение pItem* pei = (pItem*)api; будет компилироваться, потому чтооно эквивалентно pItem* pei = (pItem*)(&api[0]);

. Выражение pItem* pei = (pItem*)ei; не будет компилироваться, поскольку оно пытается привести объект типа структуры (значение) к указателю на некоторый не связанный тип.

Выражение, которое вы использовали, pItem* pei = (pItem*)(&ei); создает указатель на объект структуры и интерпретирует его как указатель на pItem.Поскольку pItem является первым элементом структуры, он расположен по тому же адресу памяти, что и ei, и это работает.(это даже гарантируется стандартом, §6.7.2.1 / 13: «указатель на объект структуры, соответствующим образом преобразованный, указывает на его начальный член»)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...