为何这段C程序输出为2,0而非0,0?与字节序有关吗?
为什么这段C程序输出2,0而非0,0?和字节序有关吗?
首先给出程序代码:
#include <stdio.h> int main(){ int arr[3] = {2, 3, 4}; char *p; p = arr; p = (char*)((int*)(p)); printf("%d, ", *p); p = (int*)(p+1); printf("%d", *p); return 0; }
核心结论:
输出2,0确实和字节序(endianness)直接相关,第二个输出则是环境特定的未定义行为表现,具体拆解如下:
第一个输出
2的原因(字节序的直接影响)- 假设当前运行环境是32位int(占4字节)的小端序架构(比如常见的x86/x86_64):
- 数组元素
arr[0] = 2会按「低字节存低地址」的小端规则存储,4字节内存布局为:0x02 0x00 0x00 0x00 p = arr将int数组的首地址(即arr[0]的低字节地址)赋值给char*指针p,*p读取该地址的单个字节,得到0x02,转成int输出就是2。
- 数组元素
- 如果是大端序架构,
arr[0] = 2的内存布局是0x00 0x00 0x00 0x02,此时*p读取的首字节是0x00,第一个输出就会是0。
- 假设当前运行环境是32位int(占4字节)的小端序架构(比如常见的x86/x86_64):
第二个输出
0的原因(环境依赖的未定义行为)p = (int*)(p+1):char指针p加1后,指向arr[0]的第二个字节(值为0x00),随后强制转换成int*指针。- 这个操作违反了C标准的类型别名规则,同时属于非对齐内存访问,因此是未定义行为——C标准不保证输出结果,但在x86这类允许非对齐访问的架构中,会执行连续4字节的读取:
- 从
p+1的地址开始读取4个字节,由于arr[0]的后三个字节都是0x00,若后续内存恰好也为0x00,最终读取到的int值就会是0。
- 从
- 注意:该输出结果是环境依赖的,换其他架构或环境可能得到不同值。
补充说明
代码中p = (char*)((int*)(p));是冗余操作,将char转成int再转回char*,不会改变指针指向,对程序逻辑无影响。
内容的提问来源于stack exchange,提问作者Serket
相关产品推荐
相关产品推荐

