大家。
这是我写的测试程序。
#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 = π
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
答案 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保证:“指向结构对象的指针,适当转换,指向其初始成员”)