unsigned short val1 = 0xa500;
short val2 = 0xa500;
printf("%0x\n",val1);//输出a500
printf("%0x\n",val2);//输出ffffa500
unsigned short val1 = 0xa500;
short val2 = 0xa500;
printf("%0x\n",val1);//输出a500
printf("%0x\n",val2);//输出ffffa500
当把0xa500
赋值给一个2字节变量时,其二进制是1010010100000000
,对于这么一个16位二进制,解读为16位无符号整数就是0xa500
,解读为16位有符号整数就是-23296
(自行根据反补码规则解读)
然后问题来了
当你用在printf
中以%x
输出时,注意,%x
意味着输出一个四字节十六进制整数,所以此时你的变量已经被隐式转换到四字节了!
对于正整数,隐式转换就是在前面补0,即变为00000000000000001010010100000000
,即0xa500
然而对于负数,隐式转换会按照负数补码规则,在高16位填充1,变成11111111111111111010010100000000
,即0xffffa500
了
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
因为short的范围是-32768到32767,而0xa500是42240,超过范围了,实际是-23296,所以会按补码来存,低16位的补码是a500,高16位是符号位,-1的补码是ffff,因此一起就是0xffffa500
而unsigned short的范围是0到65535,没超范围,所以一切正常