【问题标题】:How does operator precedence actually work in this program?运算符优先级在这个程序中实际上是如何工作的?
【发布时间】:2017-03-11 07:56:04
【问题描述】:
#include<stdio.h>
int main()
{
        int i=-1, j=-1, k=-1, l=2, m;
        m = (i++ && j++ && k++) || (l++);
        printf("%d %d %d %d %d", i, j, k, l, m);
}

我对在给定程序中评估逻辑表达式时运算符优先级的工作方式感到困惑。

变量m 将被分配01,具体取决于它后面的逻辑表达式的值。

将评估第一个括号,两个 AND 运算的总体结果将为真或1。但是,由于使用了短路逻辑 OR,因此不会对第二个括号进行评估。

所以,我的问题是,如果括号的优先级高于该表达式中的所有其他运算符,为什么不先评估两个括号,然后执行 OR 操作? 也就是为什么输出的是0 0 0 2 1而不是0 0 0 3 1

编辑: 我所问的与this 有所不同(建议重复) 因为我强调括号括住 OR 运算符的第二个操作数。

【问题讨论】:

  • 请注意,如果第一个带括号的表达式为真,短路评估将不会评估(l++) 或其副作用。括号没有区别,(l++)l++完全相同
  • ...与第一部分类似:如果 i == 0 则不计算接下来的两个表达式,并且不会发生大小效应 j++k++。这是一种危险的代码编写方式!
  • @BoPersson:不完全是重复的,但上述问题的答案之一也有帮助:stackoverflow.com/a/31779475/1866196

标签: c logical-operators operator-precedence short-circuiting logical-or


【解决方案1】:

当存在歧义时,运算符优先级生效。

在这种情况下,规范非常明确。

如果|| 运算符的任一操作数与0 比较不相等,则该运算符将产生1;否则,它 产生0。结果类型为int

而且,(强调我的

与按位| 运算符不同,|| 运算符保证从左到右的评估;如果 第二个操作数被求值,第一个求值之间有一个序列点 和第二个操作数。如果第一个操作数与0 比较不相等,则第二个操作数是 未评估。

在你的情况下,

 (i++ && j++ && k++) || (l++);

(i++ &amp;&amp; j++ &amp;&amp; k++) 是左操作数,(l++); 是右操作数,其余的应该很清楚。 :)

【讨论】:

  • @Deniz 非常正确,但这与优先级并不完全相关。这就是前后自增运算符的行为方式。
【解决方案2】:

运算符优先级(和关联性)仅决定表达式的解析方式。将它与 操作数的求值顺序 混淆是一个常见的错误,这是不同的事情。在这个例子中,运算符优先级是相当不相关的。

对于 C 中的大多数运算符,未指定操作数的计算顺序。如果你写了true | l++,那么l++ 就会被执行。 “短路评估”是您的代码中不会发生这种情况的原因。 &amp;&amp; || 运算符是一种特殊情况,因为它们明确定义了求值顺序。 || 的右操作数保证不会在左操作数的计算结果为非零的情况下被计算。

【讨论】:

    猜你喜欢
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 2019-02-02
    相关资源
    最近更新 更多