C语言printf用%x输出signed char时出现ffffff前缀的原因

产生该输出的核心原因
你的猜测基本正确,本质是C语言的有符号数整型提升规则和%x格式符的解析逻辑共同作用的结果:
- 从输出反推,你的指针
p3是signed char(多数编译环境下默认char为有符号类型)类型的指针,*(p3 + 3)取到的单字节值是0x90。对有符号char来说,最高位为1代表是负数,0x90实际对应的有符号值是-112。 - 给
printf这类可变参数函数传参时,所有长度小于int的整型值都会触发默认整型提升:有符号类型提升时会做符号位扩展——如果原值的最高符号位是1,提升为32位int时,高24位会全部补1,最终单字节的0x90提升后就变成了32位int值0xffffff90。 %x格式符的作用是将传入的参数按无符号整型解析为十六进制输出,它不会自动截断低字节,会直接把接收到的32位值全部转成十六进制打印,所以最终输出就是ffffff90,而非你预期的90。
修正方法
如果想要得到90的输出,任选以下一种修改方式即可:
- 将
p3的类型改为unsigned char*:无符号char做整型提升时高位统一补0,提升后的值为0x00000090,用%x输出就会得到90 - 传参时手动做无符号截断:写为
printf("%x", (unsigned char)*(p3 + 3)),强转为无符号char后再参与整型提升,高位会补0 - 给格式符加长度修饰符:写为
printf("%hhx", *(p3 + 3)),hh修饰符会告知printf该参数对应单字节长度,输出时只会取低8位做转换,不会打印高位的f
注意:
%x本身要求传入的参数是无符号整型类型,如果传入有符号int值,会直接按内存里的二进制位解析为无符号数,不会自动做符号处理。
内容的提问来源于stack exchange,提问作者as df
相关产品推荐
相关产品推荐

