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

为何这段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)直接相关,第二个输出则是环境特定的未定义行为表现,具体拆解如下:

  1. 第一个输出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。
  2. 第二个输出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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:57:28