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

C语言中printf输出ffffffb1而非b1的原因咨询

问题解析:有符号char的符号扩展导致输出异常

这是个非常典型的有符号字符的符号扩展问题,咱们一步步把它拆解清楚:

先确认已知前提

你的Intel i7处理器是小端字节序,所以unsigned int x = 0x15b11056在内存里的存储顺序(从低地址到高地址)是:

  • 第1个地址:0x56
  • 第2个地址:0x10
  • 第3个地址:0xb1
  • 第4个地址:0x15
    这和你观察到的输出规律完全一致,小端序的部分没有问题。

核心原因:默认char是有符号类型

在绝大多数C编译器(包括你用的在线IDE的编译器)中,char类型默认是signed char(有符号字符)。当你用*(c+2)取出第3个地址的0xb1时:

  • 0xb1的二进制是10110001,最高位是1,对于signed char来说,这代表一个负数(对应十进制-79,遵循补码规则)。
  • 当你把这个signed char值传给printf的%x格式符时,会触发整数提升:signed char会被提升为int类型。为了保持负数的数值不变,提升时会把高位全部补1,于是8位的0xb1就变成了32位int的0xffffffb1,这就是你看到的异常输出。

而之前用0x15711056时,第3个地址的0x71二进制是01110001,最高位是0,作为signed char是正数,提升为int时高位补0,所以输出还是0x71,符合你的预期。

解决方法

有两种简单的方式可以解决这个问题:

  • 方式1:将字符指针声明为无符号类型
    修改指针定义为:
    unsigned char *c = (unsigned char*) &x;
    
    这样取出的字节会被当作无符号值,提升为int时高位补0,0xb1就会正常输出为0xb1。
  • 方式2:打印时强制转换为无符号字符
    不需要修改指针,在打印时做类型转换:
    printf("Value at third address %x\n", (unsigned char)*(c+2));
    

额外验证

你可以自己测试一下:如果把x改成0x15811056,第3个地址的0x81也会触发同样的符号扩展,输出0xffffff81,这就能验证咱们的结论啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:48:36