You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求解析C语言结构体大小及代码各输出结果的原因

这段C语言代码的输出详解

先贴出原代码:

struct X {struct X *p; short a, *b;};
struct X x, *p=&x;
printf("0:%x\n", p);
printf("1:%x\n", sizeof(*p));
printf("2:%x\n", &p->a);
printf("3:%x\n", &p->b);
printf("4:%x\n", ++p);
printf("5:%x\n", p-&x);
printf("6:%x\n", &x-p);

对应的输出(根据你提供的图片整理):

0:7ffeefbff5e0
1:18
2:7ffeefbff5e8
3:7ffeefbff5ea
4:7ffeefbff5f2
5:1
6:ffffffff

下面逐个解释每一行输出的逻辑:

1. 输出0:p的地址

p是指向结构体变量x的指针,这里输出的是x在栈内存中的起始地址,不同运行环境下这个值会不一样,属于正常现象。

2. 输出1:sizeof(*p)=18的原因

*p等价于struct X类型,它的大小由成员大小和内存布局决定:

  • 64位系统下,指针类型占8字节,所以struct X *p和short *b各占8字节
  • short a是短整型,占2字节

三个成员的总大小是8+2+8=18,这里没有额外的内存填充,说明当前编译环境没有强制要求结构体总大小对齐到最大成员(8字节)的倍数(C标准允许这种情况,只是部分架构下不对齐的指针访问会有性能损耗)。

3. 输出2:&p->a的地址

结构体成员在内存中按声明顺序排列,第一个成员p占8字节,所以第二个成员a的起始地址是x的起始地址加8,也就是0x7ffeefbff5e0 + 8 = 0x7ffeefbff5e8,和输出完全匹配。

4. 输出3:&p->b的地址

a是2字节的短整型,所以第三个成员b的起始地址是a的地址加2,也就是0x7ffeefbff5e8 + 2 = 0x7ffeefbff5ea,和输出一致。

5. 输出4:++p的结果

指针自增的步长是指向类型的大小,也就是sizeof(struct X)=18(十六进制为0x12)。p原本指向0x7ffeefbff5e0,自增后地址变为0x7ffeefbff5e0 + 0x12 = 0x7ffeefbff5f2,和输出一致。

6. 输出5:p-&x的结果

C语言中同类型指针相减,结果是两个指针之间相差的元素个数,而非字节数。p现在指向x之后的下一个struct X位置,所以差值是1,输出1。

7. 输出6:&x-p的结果

这是&x - p,计算得0 - 1 = -1。因为printf用了%x格式符,会把数值当作无符号十六进制输出,-1的32位无符号表示是ffffffff(这里输出32位是因为%x默认处理32位整数,64位指针被截断了)。

内容的提问来源于stack exchange,提问作者KeyboardSound

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:23:22