C中的短路和操作员优先

问题描述 投票:1回答:3

我知道C中的逻辑运算符会发生短路,但是我怀疑这是短路,并且运算符优先级规则不会相互冲突。参见以下示例:

#include<stdio.h>
int main()
{
    int a;
    int b=5;

    a=0 && --b;
    printf("%d %d",a,b);

    return 0;
}

根据优先级规则,最高优先级是前缀运算符。因此,应先评估--b,然后再评估&&,最后将结果分配给a。因此,预期输出应为0 4。但是在这种情况下,&&的第二个操作数实际上不会执行,结果是0 5

为什么优先级规则未在此处应用。逻辑运算符是否免除形式优先规则?如果是,还有哪些其他运算符显示这种行为?这种行为背后的逻辑是什么?

c operators logical-operators operator-precedence short-circuiting
3个回答
1
投票

Precedence影响如何解析歧义表达式。当使用多种运算符来解释表达式的方式有多种时,优先级会告诉我们哪种解释是正确的。将优先级视为一种找出隐含括号在哪里的机制。

例如,在所讨论的语句中,有两种有效的方法来解析它。如果=的优先级高于&&,则可以理解为:

(a = 0) && --b;

但是由于&&具有更高的优先级,因此实际上被解释为:

a = (0 && --b);

评估顺序与优先级不同。它们是相关但独立的概念。在使用优先级确定表达式的正确解析之后,评估顺序告诉我们评估操作数的顺序。它是从左到右吗?是右到左吗?反了?在外面?未指定?

大部分情况下,未指定评估顺序。像+*<<这样的运算符没有定义的评估顺序。允许编译器做任何喜欢的事情,并且程序员不得编写依赖于任何特定顺序的代码。

=&&是例外。 =总是从右到左求值,&&则从左到右有短路。

  1. [a = (0 && --b)=从右到左求值
    1. [0 && --b&&从左到右评估为短路
      1. [0,评估为false会触发短路并取消下一步]
      2. [--b,由于短路而未评估
      3. 结果为0
    2. [a,已评估变量引用
    3. [a = 0,发生分配,总结果为0

0
投票

运算符优先级并不一定告诉您先执行表达式,这只是意味着要对表达式进行解析,以便将较高优先级运算的结果用于较低优先级运算中,而不是相反。仅在需要时才对实际表达式求值!


0
投票

您正在混淆两个相关但不同的主题:运算符优先级评估顺序

运算符优先级规则规定了如何将各种运算符组合在一起。对于此表达式:

 a=0 && --b;

运算符按如下方式分组:

 a = (0 && (--b));

然而,这对操作数的求值顺序没有影响。&&运算符特别要求首先对左操作数求值,如果其求值为0,则不对右操作数求值。

因此,在这种情况下,&&的左侧为0,因此,由于其值为0,因此不评估--b的右侧,因此b不递增。


-1
投票

这与优先级无关。该表达式从左到右求值。

a = 0的值为false,因此无需评估表达式的第二部分,因为false && truefalse,给定表达式的第一部分为false,则表达式将始终为[ C0],如果您有false运算符,则必须对表达式的第二部分求值。

© www.soinside.com 2019 - 2024. All rights reserved.