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

a87*_*874 6 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;
}
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么这段代码的输出是no.

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

chq*_*lie 11

你正在比较unsigned int一个signed char.这种比较的语义是反直觉的:在将有符号值转换为无符号后(如果两个操作数在提升后具有相同的大小)之后,大多数涉及signedunsigned操作数的二进制操作都在无符号操作数上执行.以下是步骤:

  • signed char值将提升为int具有相同值的值-23.
  • 比较将在int和C 上进行unsigned int,共同类型unsigned int如C标准中所定义.
  • int被转换为unsigned int具有值UINT_MAX - 23,一个很大的数字.
  • unsigned int值执行比较:值23越小,比较结果为false.
  • else分支进行评价时,no被打印.

更糟糕的是,如果c已经被定义为一个long,结果会依赖于是否longint具有相同的大小与否.在Windows上,它会打印no,而在64位Linux上,它会打印yes.

切勿在比较中混合有符号和无符号值.启用编译器警告以防止出现此类错误(-Wall-Weverything).你也可以将所有这些警告致命,-Werror以完全避免这种命运多code的代码.

有关完整参考,请阅读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