【问题标题】:Strange integer comparison in CC中奇怪的整数比较
【发布时间】:2012-02-09 11:09:39
【问题描述】:

我正在用 C 编写简单的程序,但我不明白为什么:

printf("%d\n", 1 == 1 == 1);
printf("%d\n", 1 == 1);
printf("%d\n", 0 == 0 == 0);
printf("%d\n", 0 == 0);

给予:

1
1
0
1

我习惯了 Python,所以这一切对我来说都是新的和陌生的。

(顺便说一句,谁是发明者?)

【问题讨论】:

  • 这里没有什么奇怪的,除了括号不好的表达式。编程第一定律 - 将问题(在本例中为表达式)分解为小到足以让您理解的部分。

标签: c comparison boolean


【解决方案1】:

我认为 C 是指外星人,而不是人类。

也许吧。没有人会编写代码为1 == 1 == 1

不管怎样,这里发生了什么。该表达式被 AFAIK 解析为(1 == 1) == 1,因此它是另一个比较结果与 1 的比较。真值在 C 中表示为整数;真为 1,假为 0。所以1 == 1 为 1(真),等于 1。

0 == 0 == 0类似:

(0 == 0) == 0
1 == 0 // 0 == 0 is true (1)
0 // 1 == 0 is false (0)

【讨论】:

  • 这只是一个测试。我想检查 a == b == true (1)。而且我是人类……我想。
  • @Lundin 您将优先级的句法概念与评估顺序的动态概念混淆了。 1 == 1 == 1 的关联性由例如完美定义。 C99 6.5.9:1。不涉及未定义的行为。
  • @Lundin 这是使用 C99 6.5.9:1 语法对 AST (1 == 1) == 1 的派生。 E → E == R → (E == R) == R。你如何以与该语法兼容的方式导出1 == (1 == 1)? PS:是的,你说的是“未指定”,确实很不一样,对不起。
  • @Lundin 在与 6.5:3 相同的页面上,作为脚注 72 的一部分,有一句话“在每个主要子条款中,运算符具有相同的优先级。指示了左或右结合性在每个子条款中按其中讨论的表达式的语法。"
  • @Lundin 该语法通过仅允许您从具体语法 1 == 1 == 1 派生 AST (1 == 1) == 1 来指示运算符 == 的左关联性或右关联性。请阅读脚注 72。或者,如果这对您更有说服力,请尝试推导出 1 == (1 == 1)
【解决方案2】:

你需要了解

  1. 运算符优先级 (http://www.swansontec.com/sopc.html)。
  2. 在 C/C++ 中,0 等价于假,任何非零整数都等价于真。
  3. bool 类型可隐式转换为整数,0 转换为 false,1 转换为 true。

因此1 == 1 == 1 被评估为(1 == 1) == 1 --> true == 1 --> trueprintf("%d\n", 1 == 1 == 1) --> printf("%d\n", true) --> printf("%d\n", (int)true) --> printf("%d\n", 1) --> 1

【讨论】:

  • 运营商在场与这个问题无关。 1 == 1 == 1 可以评估为(1 == 1) == 11 == (1 == 1),并且您不知道哪个适用。这称为“评估顺序”,适用的是未指定的行为。
  • @Lundin 很抱歉重复一遍,但你说反了。此示例与优先级有关,与评估顺序无关。
  • @Complicatedseebio 您是如何得出这样的结论,即运算符优先级在仅使用一种运算符(即==)的表达式中很重要?如果您查看标准或常用优先表之一,您肯定会在与 == 运算符相同的行中找到 == 运算符...
【解决方案3】:

== 运算符的结果是 1 如果两个操作数具有相同的值,则为 0 如果两个值不同。

【讨论】:

    猜你喜欢
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2018-06-02
    • 2015-02-17
    • 2022-01-03
    相关资源
    最近更新 更多