为什么这个C代码的输出是"没有"?

时间:2016-07-17 06:10:58

标签: c comparison-operators unsigned-integer

我遇到了这个问题。

#include <stdio.h>

int main(void) {
    // your code goes here
    unsigned int i = 23;
    signed char c = -23;

    if (i > c)
        printf("yes");
    else
        printf("no");

    return 0;
}

我无法理解为什么此代码的输出是no

在C中intchar之间进行比较时,有人可以帮助我了解比较运算符的工作原理吗?

1 个答案:

答案 0 :(得分:11)

您正在将unsigned intsigned char进行比较。这种比较的语义是违反直觉的:大多数涉及signedunsigned操作数的二进制操作是在将有符号值转换为无符号后(如果两个操作数具有相同的大小后)对无符号操作数执行的推广)。以下是步骤:

  • signed char值会提升为具有相同值int的{​​{1}}。
  • 将在-23int上进行比较,常见类型为{C}标准中定义的unsigned int
  • unsigned int转换为int,其值为unsigned int,数字非常大。
  • UINT_MAX - 23值执行比较:unsigned int是较小的值,比较的结果为false。
  • 评估23分支,打印else

更糟糕的是,如果no被定义为c,结果将取决于longlong是否具有相同的大小。在Windows上,它将打印int,而在64位Linux上,它将打印no

切勿在比较中混合有符号和无符号值。启用编译器警告以防止出现此类错误(yes-Wall)。您可以使用-Weverything使所有这些警告致命,以完全避免使用这种命运不佳的代码。

如需完整参考,请阅读 6.3转换下的C标准(C11)的以下部分:

  • 整数促销 6.3.1.1布尔,字符和整数中进行了解释。
  • 操作数转换详见 6.3.1.8常规算术转换

您可以从工作组网站下载最新的C11标准草案:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf