【问题标题】:How does this boolean expression work [duplicate]这个布尔表达式如何工作[重复]
【发布时间】:2014-08-15 15:49:54
【问题描述】:

以下程序的输出与我预期的不一样。请向我解释一下逻辑表达式在该程序中的工作原理。

#include<stdio.h>
int main()
{
    int i=-3, j=2, k=0, m;
    m = ++i || ++j && ++k;
    printf("%d, %d, %d, %d\n", i, j, k, m);
    return 0;
}

我预期的输出是 -2, 3, 1, 1 输出为 -2, 2, 0, 1 为什么 j 和 k 不增加

【问题讨论】:

标签: c


【解决方案1】:

由于 ++i 不为零,因此为真,因此该语句的求值停止并返回真

true || (++j && ++k)

始终为真,并且无需计算 || 之后的位即可。因此它不会改变 j 或 k

【讨论】:

  • 小补充:一些编译器选项允许不短路,并产生预期的输出。检查您的特定编译器文档。
  • 有不会短路的C编译器?! - 我很惊讶。如此多的 C 代码依赖于这种行为。阅读代码的人类也会期待它
  • @pm100 见here,有保证
  • 需要注意,短路的目的是为了节省CPU周期。
  • 是的 - 它是,但它现在依赖于每个地方。您多久看到一次 if(ptr != null && ptr->flag)。如果没有短路,代码就会失败
【解决方案2】:
由于||短路 特性,

jk 不会递增。 ++i || ++j &amp;&amp; ++k 的评估在 ++i 被评估为非零(即为真)之后立即停止。

【讨论】:

    【解决方案3】:

    当你有一个布尔表达式时,它的一部分可能足以得到结果。例如,-2 || 3 &amp;&amp; 1(-2) || (3&amp;&amp;1) 相同。所以如果(-2) 产生true,整个表达式产生true,并且不需要计算表达式的其余部分。这样,++j &amp;&amp; ++k 永远不会被执行。

    您可能还想试试这个:

    #include<stdio.h>
    int main()
    {
        int i=-3, j=2, k=0, m;
        m = ++j && ++k || ++i;
        printf("%d, %d, %d, %d\n", i, j, k, m);
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      如果我是对的(如果我错了,请有人纠正我),它会计算 ++i(它返回一个非零值),所以 ++i 是“真”,而不是编译器看到 ||,它前面有一个“true”表达式,因此它跳过行并返回“true”(1)。程序从不执行 ++j 和 ++k。

      【讨论】:

      • 是的,你是对的。请参阅 Wojitek Surowka 的回答,该行为由 C 标准保证。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      • 2012-05-17
      • 2022-12-15
      相关资源
      最近更新 更多