C中结构和数组之间的本质区别

时间:2011-08-26 02:03:39

标签: c arrays struct

大家。

这是我写的测试程序。

#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 的初始化都是 {&amp; i} 。所以我猜 pItem * pei =(pItem *)ei 应该有效,但是失败了。谁能告诉我 ei api 之间的区别?它似乎与编译器处理struct和array的方式有关,我不擅长。我需要一个具体的解释。提前谢谢。

祝福

Jfhu

1 个答案:

答案 0 :(得分:2)

不同之处在于,在大多数情况下,数组名称被隐式转换为指向其第一个元素的指针,而struct类型的对象的名称则不是。

表达式pItem* pei = (pItem*)api;将被编译,因为它等同于pItem* pei = (pItem*)(&api[0]);

表达式pItem* pei = (pItem*)ei;无法编译,因为它试图将struct type(一个值)的对象强制转换为指向某个不相关类型的指针。

您使用的表达式pItem* pei = (pItem*)(&ei);创建一个指向struct对象的指针,并将其重新解释为指向pItem的指针。由于pItem是结构的第一个元素,因此它位于与ei相同的内存地址,这是有效的。 (这甚至可以通过标准§6.7.2.1/ 13保证:“指向结构对象的指针,适当转换,指向其初始成员”)