以下代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct mytype {
int x; int y; int z;
} mytype;
int main ()
{
mytype* p = (mytype*)4;
void* pp = &(p->x);
printf("%d\n",(int)pp);
}
按预期打印“4”。
但如果我更改了这一行:
void* pp = &(p->x);
致:
void* pp = &(p->y);
打印“8”。此外,如果我将其更改为p-> z,则会打印“12”。
为什么?
答案 0 :(得分:3)
mytype* p = (mytype*)4;
声明指向地址mytype
的{{1}}类型的指针。
0x04
表明void* pp = &(p->x);
printf("%d\n",(int)pp);
的地址与mytype->x
的地址相同。
重复mytype
和p->y
会在您的平台上显示p->z
,并且编译器在sizeof(int)==4
的成员之间未插入填充
如果您在不同平台上运行代码,mytype
,x
和y
之间的偏移量可能会发生变化。
另请注意我认为
z
依赖于未定义的行为,因为无法保证printf("%d\n",(int)pp);
sizeof(void*) == sizeof(int)
应该更安全。
答案 1 :(得分:1)
你拿指针,然后把它指向地址4.你的struct(x)的第一个成员将驻留在这里,所以如果你打印x的内存地址,那么你就是想要获得自己的内容出发地(4)。当你尝试打印y时,它从8开始,因为它是一个int(并且x开始,4开始变为8)。与z相同(从12开始,到16开始,y从8开始,到12结束)
虽然那里没有结构,但是你将内存转换到你的结构,所以你的指针算法将遵循你的结构的内存布局。