为什么会这样
unsigned char k=-1
if(k==-1)
是假的
unsigned int k=-1
if(k==-1)
是真的
答案 0 :(得分:19)
出于演示的目的,我们假设8位char
和32位int
。
unsigned char k=-1;
k
被赋值为255。
if(k==-1)
==
运算符的左侧是unsigned char
。右侧是int
。由于unsigned char
的所有可能值都可以放在int
内,因此左侧会转换为int
(这是由于整数促销而执行的,如下所述)。这导致比较(255 == -1)
,这是错误的。
unsigned int k=-1
k
被赋值4294967295
if(k==-1)
这一次,左侧(unsigned int)不能适合int。标准说在这种情况下,两个值都转换为unsigned int。因此,这会产生比较(4294967295 == 4294967295)
,这是真的。
标准的相关引用:
整数促销:(C99,6.3.1.1p2)
如果int可以表示原始类型的所有值,则该值将转换为int;否则,它将转换为unsigned int。
通常的算术转换:(6.3.1.8)。
[对于积分操作数],在两个操作数上执行整数提升。然后将以下规则应用于提升的操作数:
- 如果两个操作数具有相同的类型,则不需要进一步转换 ...
- 否则,如果具有无符号整数类型的操作数的等级大于或等于 等于另一个操作数的类型的等级,然后是操作数 有符号整数类型转换为带有unsigned的操作数的类型 整数类型。
...
答案 1 :(得分:1)
如果int可以表示原始类型的所有值(限制为 通过宽度,对于位字段),该值被转换为int; 否则,它将转换为unsigned int。这些被称为 整数提升.58)所有其他类型的整数不变 促销。
在第二种情况下,int不能代表unsigned int k
,因为它超出了范围。两个操作数最终都转换为unsigned int
并比较相等。
答案 2 :(得分:0)
由于未签名促销中没有符号扩展名,因此结果不同。
unsigned char k
从unsigned char(value = 255)提升为int(value = 255)。
在unsigned int k
的情况下,-1从int(value = -1)提升为unsigned int(value = 2 ^ 32-1)。
答案 3 :(得分:0)
unsigned char k = -1;
-1是int
类型的整数文字,相当于signed int
。当您将较大的有符号整数分配给较小的无符号类型时,结果将以未定义的方式截断,C标准不保证会发生什么。
在C标准之外的现实世界中,这是最有可能的(假设32位CPU,两个补码):
-1是0xFFFFFFFF。 0xFFFFFFFF的最低有效字节将分配给k
。 k == 255
。尝试使用printf("%u")
进行打印,然后亲眼看看。
在unsigned int k=-1
的情况下,-1仍然是有符号的int。但是当它存储在k
中时,它会被隐式(无声地)提升为unsigned int。稍后比较k == -1
时,右侧-1将再次升级为无符号类型,并将与k
中存储的数据进行比较。