无符号整数和无符号字符保持相同的值但行为不同为什么?

时间:2013-05-27 11:11:31

标签: c

为什么会这样

unsigned char k=-1
if(k==-1)

是假的

unsigned int k=-1
if(k==-1)

是真的

4 个答案:

答案 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)

C11标准草案的§6.3.1.1p2(n1570.pdf):

  

如果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的最低有效字节将分配给kk == 255。尝试使用printf("%u")进行打印,然后亲眼看看。

unsigned int k=-1的情况下,-1仍然是有符号的int。但是当它存储在k中时,它会被隐式(无声地)提升为unsigned int。稍后比较k == -1时,右侧-1将再次升级为无符号类型,并将与k中存储的数据进行比较。