我注意到了一些奇怪的事情,如果有人能帮助我更深入地了解正在发生的事情,我将不胜感激。
temp1 = 0x3a
temp2 = 0xfb
printf("%x", abs(temp1 - temp2))
如果 temp1、temp2 的类型为int8_t
,将打印0x3f
。
如果 temp1、temp2 的类型为int16_t
,将打印0xc1
。
如果 temp1、temp2 的类型为uint8_t
,将打印0xc1
。
现在我明白int16_8和uint8_t有更大的正范围,但我仍然不明白发生了什么,我尝试了int8_t并使用铸造
printf("%x", abs((int16_t) (temp1) - (int16_t)(temp2)))
程序打印0x3f
(我预计会得到0xc1
),这真的很令人困惑
如果temp1
和temp2
的类型为int8_t
,则temp1 = 0x3a
temp1
设置为58(0x3a
的值),但它是由实现定义的temp2 = 0xfb
设置temp2
,因为0xfb
(251)的值对于int8_t
来说太大了。通常,C 实现会将其设置为 −5(等于 251−256,并且在二进制补码中具有与 251 在无符号二进制中相同的位编码)。
那么temp1 - temp2
是 58 − −5 = 63,其中绝对值为 63,即0x3f
的值。
如果temp1
和temp2
的类型为int16_t
或uint8_t
,则temp1 = 0x3a
像以前一样将temp1
设置为 58,temp2 = 0xfb
设置为temp2
设置为 251。
则temp1 - temp2
是 58 − 251 = −193,其中绝对值为 193,即0xc1
的值。注意,在temp1 - temp2
的求值中,类型int16_t
或uint8_t
的值会自动提升为int
,因此算术是使用int
类型完成的,即使temp1
和temp2
的类型uint8_t
,也会产生-193。