我在解决为什么输出在每种特定情况下都不同时遇到了问题。在示例代码a中,有一个我预期的变量促销,结果是> 6
,但在示例代码b中,结果为<= 6
:
/* **Code a** */
puts("Code a\n");
unsigned int a = 6;
int b = -20;
( a+b > 6) ? puts("> 6\n") : puts("<= 6\n");
/* **Code b** */
puts("Code b:\n");
uint8_t a1 = 6;
int8_t b1 = -20;
( a1+b1 > 6) ? puts("> 6\n") : puts("<= 6\n");
输出:
Code a
> 6
Code b:
<= 6
答案 0 :(得分:9)
通常的算术转换是在加法操作数上执行的。对于整数类型,如果需要,这包括整数提升,如果两个操作数不具有相同类型,则进行进一步转换以将它们带到公共类型。
在第一种情况下,没有促销活动,但int
操作数已转换为unsigned int
,因为int
无法保存unsigned int
的所有可能值。
在第二种情况下,两个操作数都被提升为int
并保持为int
,因为它们具有共同类型。
作为参考,6.5.6
添加剂运算符部分中的C11标准草案说:
如果两个操作数都具有算术类型,则执行通常的算术转换 它们。
部分6.3.1.8
通常的算术转换说:
许多期望算术类操作数的运算符会导致 以类似的方式转换和生成结果类型。 目的是为了 确定操作数和结果的通用实数类型。为了 指定的操作数,每个操作数都被转换,不改变类型 域,对应的实际类型是普通实数的类型 类型。 除非另有明确说明,否则常见的实际类型也是如此 结果的相应实际类型,其类型域为 操作数的类型域,如果它们是相同的,并且是复杂的 除此以外。这种模式称为通常的算术转换
[...]
否则,将对两个操作数执行整数提升。那么 以下规则适用于提升的操作数
[...]
- 否则,如果具有无符号整数类型的操作数的等级大于或等于 等于另一个操作数的类型的等级,然后是操作数 有符号整数类型转换为带有unsigned的操作数的类型 整数类型
[...]
可以在问题中找到关于此理由的一个很好的参考:Why must a short be converted to an int before arithmetic operations in C and C++?。