C语言中向signed char赋值0x7f以上十六进制值的异常解析
为什么将0x000000a1赋值给signed char变量后输出为0xffffffa1?
当把十六进制值0x000000a1赋值给signed char类型变量时,输出结果变成了0xffffffa1,这一现象的原因可通过以下示例和分析说明:
问题复现代码
void main(){ char testVar = 0x000000a1; printf("%x \n",testVar); // 输出 ffffffa1 printf("%d \n",testVar); // 输出 -95 }
对比示例:使用unsigned char
使用unsigned char初始化时,结果符合预期:
void main(){ unsigned char testVar = 0x000000a1; printf("%x \n",testVar); // 输出 a1 printf("%d \n",testVar); // 输出 161 }
对比示例:ASCII范围内的值
当赋值在ASCII范围0x7f(即127)以内时,结果也符合预期:
void main(){ unsigned char testVar = 0x7f; printf("%x \n",testVar); // 输出 7f printf("%d \n",testVar); // 输出 127 }
原因分析
char类型仅占用1字节内存,赋值0x000000a1时,只会保留低8位的0xa1,高位字节被直接截断。- 对于
signed char,最高位是符号位:最高位为1表示负数(如0x80对应十进制-128),最高位为0表示正数(如0x7f对应十进制127)。0xa1的二进制是10100001,最高位为1,因此被识别为负数,对应的十进制值为-95。 printf处理char类型参数时,会自动将其转换为int类型(这是C语言的默认参数提升规则)。- 当
signed char转换为int时,若原变量是负数,会执行符号扩展操作:将符号位(最高位)填充到扩展的所有高位,以此保证数值的负值属性不变。0xa1(二进制10100001)扩展为int后,高位全部补1,最终得到0xffffffa1,对应十进制的-95。
内容的提问来源于stack exchange,提问作者bangingmyheadontable
相关产品推荐
相关产品推荐

