C 无符号整数 + 整数

C unsigned int + int

为什么这段代码打印 "greater than 0"

int main()
{
  unsigned int a = 5;
  int b = -10;
  (a + b) > 0 ? printf("greater than 0") : printf("less than 0");
}

如果我这样做:

printf("%d\n", a + b);

...它打印:

-5 

你的问题

默认情况下,根据 usual arithmetic conversions

,您的 int 会升级为 unsigned int

[...] if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

解决方案

您需要将 a 转换为 int 才能使此三元组按预期工作:

((int)a + b) > 0 ? printf("greater than 0") : printf("less than 0");

无论何时在 C 中执行任何操作,参数都会根据 "Usual arithemetic conversions" 规则(规范的第 6.3.1.8 节)进行转换。它们有很多,但就本例而言,重要的是:

the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
If both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

intunsigned int 具有相同的覆盖等级,因此每当您对 intunsigned int 进行操作时,int 将转换为 unsigned.

在您的情况下,这会导致 b (-10) 的值变得非常大。然后您将 5 添加到它,它仍然非常大(但不够大以回绕回零),因此 > 的结果为真。

在您的 print 语句中,您将 a 和 b 转换为它们的有符号整数表示,然后再将它们相加。你这样做不是为了你的条件。

6.3.1.1 Boolean, characters, and integers and 6.3.1.8 Usual arithmetic conversions(感谢克里斯)

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions.

...if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

你的加法涉及一个unsigned和一个intint不能表示unsigned的所有值,所以该值被转换为一个unsigned int .