C 打印指向结构成员的指针的内容会产生意外结果

C 打印指向结构成员的指针的内容会产生意外结果,c,C,以下代码: #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); } 致: 它打印“8”。如果我把它改成p->z,它会打印“12” 为什么会

以下代码:

#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);

}
致:

它打印“8”。如果我把它改成p->z,它会打印“12”


为什么会这样?

你把指针指向4的地址。结构(x)的第一个成员将驻留在这里,因此如果您打印x的内存地址,您将登录以获得初始起始位置(4)。当您尝试打印y时,它从8开始,因为它是一个int(x开始,4到8)。与z相同(从12开始,在16结束,y开始,在8结束,在12结束)


虽然那里没有结构,但您正在将那里的内存强制转换为结构,因此指针算法将遵循结构的内存布局

你把指针指向4的地址。结构(x)的第一个成员将驻留在这里,因此如果您打印x的内存地址,您将登录以获得初始起始位置(4)。当您尝试打印y时,它从8开始,因为它是一个int(x开始,4到8)。与z相同(从12开始,在16结束,y开始,在8结束,在12结束)

mytype* p = (mytype*)4;
虽然那里没有结构,但您正在将那里的内存强制转换为结构,因此指针算法将遵循结构的内存布局

mytype* p = (mytype*)4;
在地址
0x04
处声明指向类型
mytype
的指针

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)

应该更安全

在地址
0x04
处声明指向类型
mytype
的指针

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)


应该更安全。

祝贺你。您重新定义了宏(附加偏移量为4)。不过,我有点好奇。你期待什么结果?祝贺你。您重新定义了宏(附加偏移量为4)。不过,我有点好奇。你期望得到什么结果?