【问题标题】:Why should the output of this C code be "no"? [duplicate]为什么这个 C 代码的输出应该是“否”? [复制]
【发布时间】:2016-11-19 23:34:48
【问题描述】:

我遇到了这个问题。

#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 进行比较时,有人可以帮助我理解比较运算符的工作原理吗?

【问题讨论】:

标签: c comparison-operators unsigned-integer


【解决方案1】:

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

  • signed char 值提升为具有相同值-23int
  • intunsigned int进行比较,常用类型为C标准中定义的unsigned int
  • int 转换为 unsigned int,其值为 UINT_MAX - 23,这是一个非常大的数字。
  • unsigned int 值执行比较:23 是较小的值,比较结果为假。
  • 评估else 分支,打印no

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2020-03-14
  • 2020-08-07
  • 2021-12-15
  • 1970-01-01
相关资源
最近更新 更多