You need to enable JavaScript to run this app. C语言int类型在内存中的存储规则 逐字节观测负值输出异常 是否采用补码存储
优惠活动
大模型
产品
解决方案
定价
更多

C语言int类型在内存中的存储规则 逐字节观测负值输出异常 是否采用补码存储

32位int的内存存储规则

当前所有主流桌面端C语言编译器(GCC、Clang、MSVC)的32位有符号int,完全采用二进制补码(2's complement)规则存储,且你当前运行环境为典型的小端字节序(低地址存数值的最低有效字节,高地址存最高有效字节),和你观测到的正整数输出规律完全自洽。


你之前的推导存在三个核心认知误区
  • 误区一:把补码的结构拆成了“每个字节单独携带符号位、各自按原码计算”的形式,完全违背补码的整体计算逻辑
    补码是对整个字长统一计算的,不存在每个字节单独带符号位的规则。以32位int为例,负整数的补码计算规则是:用2^32减去该负整数的绝对值,得到的32位二进制值就是实际存储的位模式。你手绘的位模式里,第一个字节用了原码格式的10010100(也就是8位原码表示的-20),但实际存储的8位补码-20是11101100,从单字节层面就和实际存储值不匹配。
  • 误区二:忽略了补码的符号扩展规则
    当小范围的带符号数(比如8位的-20)被放到更大的字长(32位int)中存储时,会把原数据的最高符号位,连续填充到高位的所有空余字节位置。比如8位宽的-20补码是11101100,最高位为1,扩展成32位时就需要把高24位全部填1,最终的完整32位补码就是11111111 11111111 11111111 11101100,不存在你之前画的10000001这类独立的错误字节位。
  • 误区三:没有考虑char类型的默认有符号属性、以及小端字节序对读取结果的影响
    绝大多数平台的char类型默认是8位带符号整数,同时小端存储会把32位int的最低字节放到内存最低地址:
    • 当你把int指针强制转成char指针逐字节读取时,每个单字节会直接按8位带符号补码规则转成十进制
    • 比如单字节0xFF作为8位带符号数时,十进制值就是-1,不是无符号表示的255

观测结果和补码规则的对应验证

把你测试的四个输入逐一代入补码、小端存储的逻辑,完全可以和输出结果匹配:

  1. 输入127:32位补码为0x0000007F,小端从低地址到高地址的字节依次是0x7F(127)、0x00(0)、0x00(0)、0x00(0),和输出完全一致
  2. 输入256:32位补码为0x00000100,小端从低地址到高地址的字节依次是0x00(0)、0x01(1)、0x00(0)、0x00(0),和输出完全一致
  3. 输入-20:32位补码为0xFFFFFFEC,小端从低地址到高地址的字节依次是0xEC(作为8位带符号数对应-20)、0xFF(作为8位带符号数对应-1)、0xFF(-1)、0xFF(-1),和输出完全一致
  4. 输入-256:32位补码为0xFFFFFF00,小端从低地址到高地址的字节依次是0x00(0)、0xFF(-1)、0xFF(-1)、0xFF(-1),和输出完全一致

你之前自己手绘的负整数位模式本质是把原码、独立符号位的概念套到补码存储上,和实际内存的位结构完全脱节。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 13:24:03