3

为什么会这样

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

是假的

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

是真的

4

4 回答 4

19

为了演示的目的,让我们假设 8-bitchar和 32-bit int

unsigned char k=-1;

k赋值为 255。

if(k==-1)

==运算符的左侧是unsigned char. 右手边是一个int。由于 an 的所有可能值都unsigned char可以放入 anint中,因此左侧将转换为 an int(这是由于整数提升而执行的,引用如下)。这导致比较(255 == -1),这是错误的。


unsigned int k=-1

k被赋值为 4294967295

if(k==-1)

这一次,左侧(无符号整数)不能放入整数。标准规定,在这种情况下,两个值都转换为无符号整数。所以这导致比较(4294967295 == 4294967295),这是真的。


标准中的相关引用:

整数促销:(C99,6.3.1.1p2)

如果一个 int 可以表示原始类型的所有值,则将该值转换为 int;否则,它将转换为无符号整数。

通常的算术转换:(6.3.1.8)。

[对于整数操作数,] 整数提升在两个操作数上执行。然后将以下规则应用于提升的操作数:
- 如果两个操作数具有相同的类型,则不需要进一步转换。
...
- 否则,如果无符号整数类型的操作数的等级大于或等于另一个操作数类型的等级,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
...

于 2013-05-27T11:21:03.977 回答
1

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

如果 int 可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为 int;否则,它将转换为无符号整数。这些被称为整数提升。58) 所有其他类型都不受整数提升的影响。

在第二种情况下, int 无法表示unsigned int k,因为它超出了范围。两个操作数最终都被转换为unsigned int并比较相等。

于 2013-05-27T11:27:54.120 回答
0

由于未签名促销中没有符号扩展,因此结果是不同的。

unsigned char k从 unsigned char (value=255) 提升为 int (value=255)。

在 的情况下unsigned int k,-1 从 int (value=-1) 提升为 unsigned int (value=2^32-1)。

于 2013-05-27T11:16:25.780 回答
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 仍然是有符号整数。但是当它存储在k. 当您稍后比较k == -1时,右侧的 -1 将再次提升为无符号类型,并将与存储在 中的数据进行比较k

于 2013-05-27T11:26:38.127 回答