C语言解引用指针出现意外值:%x输出前导f的原因
问题:char*类型变量用%x打印出现前导
ffffff的原因? 测试代码
#include <stdio.h> int main() { long long data = 0xFFFEABCD11112345; char *pData = (char *)&data; printf("Value at address %p is %x\n", pData, *pData); pData = pData + 5; printf("Value at address %p is %x\n", pData, *pData); return 0; }
运行输出
Value at address 00000023515FFC00 is 45 Value at address 00000023515FFC05 is ffffffab
已知pData是char*类型,预期第二个值为ab而非ffffffab,怀疑是%x格式符导致,但未完全理解,请问前导f的来源是什么?
解答
核心原因是有符号char的整数提升与符号扩展:
- 多数系统中
char默认是有符号类型(signed char)。当你把*pData(char类型)传给printf的%x格式符时,会触发C语言的整数提升规则:小于int的整数类型会被自动提升为int类型。 - 你要打印的第二个字节是
0xAB,对于有符号char来说,它的二进制最高位是1(10101011),属于负数(对应十进制-85)。 - 整数提升时,负数会进行符号扩展:用符号位(最高位的1)填充扩展出来的高位空间。32位int中,原本8位的
0xAB就会被扩展成0xFFFFFFAB,%x格式符会完整打印这个int值,所以出现了前导的ffffff。
解决方法
- 改用
unsigned char*类型指针:这样存储的是无符号值,整数提升时会用0填充高位,打印%x只会输出ab。 - 强制类型转换:打印时把
*pData转为unsigned char,比如printf("Value at address %p is %x\n", pData, (unsigned char)*pData);。 - 使用
%hhx格式符:这个格式符专门用于打印unsigned char类型,会自动截断高位,直接输出ab。
内容的提问来源于stack exchange,提问作者atta
相关产品推荐
相关产品推荐

