为何int16_t变量d的printf输出为32位,而uint16_t变量b却不是?
为何int16_t变量d的printf输出为32位,而uint16_t变量b却不是?
首先先看你的代码和运行输出:
示例代码
#include <stdio.h> #include <stdint.h> int main() { uint32_t a = 0xF0FF1FFF; printf("a = 0x%x\n",a); uint16_t b = a; printf("b = 0x%x\n",b); int32_t c = 0xF0FF8FFF; printf("c = 0x%x\n",c); int16_t d = c; printf("d = 0x%x\n",d); int32_t e = d; printf("e = 0x%x\n",e); return 0; }
运行输出
a = 0xf0ff1fff b = 0x1fff c = 0xf0ff8fff d = 0xffff8fff e = 0xffff8fff
咱们一步步拆解核心原因,主要和C语言里的整数提升以及符号扩展规则有关:
先看变量
b:它是uint16_t(无符号16位整数),赋值后的值是0x1FFF。当你把它传给printf时,C语言会自动把小整数类型提升为int(多数32/64位系统里int是32位)。因为是无符号类型,提升时会在高位补0,所以0x1FFF会变成0x00001FFF。而printf的%x格式符会省略前导零输出,所以最终显示0x1fff。再看变量
d:它是int16_t(有符号16位整数),赋值后的值是0x8FFF——这个值的最高位是1,对应有符号数的负号。当它被传给printf时,同样触发整数提升,但因为是有符号类型,提升时会执行符号扩展:为了保持数值的负号不变,会把所有高位都填充为符号位的1。于是16位的0x8FFF就被扩展成了32位的0xFFFF8FFF,printf用%x输出这个完整的32位值,就得到了0xffff8fff。
最后变量e的输出和d一致,也验证了这个逻辑:把int16_t的d赋值给int32_t的e时,同样进行了符号扩展,所以e的值也是0xFFFF8FFF。
备注:内容来源于stack exchange,提问作者Inquisitive
相关产品推荐
相关产品推荐

