我们有:
unsigned x = 1;
signed char y = -1;
这个表达式:
x > y
用作if语句的控制表达式。
在通常的算术转换之后,右操作数y 将被转换为unsigned int 值。负的signed char 值-1 的转换结果将是一个巨大的unsigned int 值(等于UINT_MAX)。
所以表达式x > y 将被计算为:
1U > UINT_MAX
始终为假(即,评估为 0)。
这是简短的版本。为了解释我们如何用 C 标准规则得出这个结果,我在下面解释一下。
事情是这样的:
使用了>关系运算符,这里是C对关系运算符的说法:
关系运算符 (C99, 6.5.8p3) “如果两个操作数都具有算术类型,则执行通常的算术转换。”
好的,在我们的示例中,操作数都是整数类型,整数类型是算术类型。所以通常的算术转换将完成。常用的算术转换有哪些?
通常的算术转换 (C99, 6.3.1.8p1) "否则,对两个操作数都执行整数提升。然后将以下规则应用于提升的操作数:`
好的,第一个整数提升是在每个操作数上完成的。整数促销如何执行?
整数提升 (C99, 6.3.1.1p2) "如果一个int可以表示原始类型的所有值,则将该值转换为int;否则,将其转换为unsigned int . 这些被称为整数提升。”
y 属于 signed char 类型,因此在整数提升之后它首先被提升为 int,而 x 属于 unsigned int 类型并保持为 unsigned int。
然后通常的算术转换会在两个操作数之间找到一个共同的类型。在我们的例子中,这意味着:
常用算术转换(套件) (C99, 6.3.1.8p1) “否则,两个操作数都转换为无符号整数类型,对应于带符号整数类型的操作数类型。”
unsigned int 与int 类型具有相同的转化排名(记住signed char 被提升为int),因此提升的y 将从int(提升后)转换为@987654344 @。有关信息,整数转换等级在 (C99, 6.3.1.1p1) 中定义。
如您所见,unsigned int 在通常的算术转换中胜过int,另一种说法是unsigned 是粘性。
现在如何将-1 的int 值(提升为int 后的signed char -1)转换为unsigned int 值?`。以下是 C 在这种特定情况下关于整数转换的说法:
整数转换 (C99, 6.3.1.3p2) "否则,如果新类型是无符号的,则通过重复加或减1来转换该值,而不是可以表示的最大值新类型,直到值在新类型的范围内。”
这一段是这样写的,所以它的含义保持独立于带符号的数字表示。对于二进制补码表示,这意味着将int 值-1 转换为(UINT_MAX + 1) - 1,等于UINT_MAX。所以在我们的具体案例中,
x > y
等价于
1U > UINT_MAX
等价于
0