我知道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
。
为什么优先级规则未在此处应用。逻辑运算符是否免除形式优先规则?如果是,还有哪些其他运算符显示这种行为?这种行为背后的逻辑是什么?
Precedence影响如何解析歧义表达式。当使用多种运算符来解释表达式的方式有多种时,优先级会告诉我们哪种解释是正确的。将优先级视为一种找出隐含括号在哪里的机制。
例如,在所讨论的语句中,有两种有效的方法来解析它。如果=
的优先级高于&&
,则可以理解为:
(a = 0) && --b;
但是由于&&
具有更高的优先级,因此实际上被解释为:
a = (0 && --b);
评估顺序与优先级不同。它们是相关但独立的概念。在使用优先级确定表达式的正确解析之后,评估顺序告诉我们评估操作数的顺序。它是从左到右吗?是右到左吗?反了?在外面?未指定?
大部分情况下,未指定评估顺序。像+
和*
和<<
这样的运算符没有定义的评估顺序。允许编译器做任何喜欢的事情,并且程序员不得编写依赖于任何特定顺序的代码。
=
和&&
是例外。 =
总是从右到左求值,&&
则从左到右有短路。
a = (0 && --b)
,=
从右到左求值0 && --b
,&&
从左到右评估为短路0
,评估为false会触发短路并取消下一步]--b
,由于短路而未评估0
a
,已评估变量引用a = 0
,发生分配,总结果为0
运算符优先级并不一定告诉您先执行表达式,这只是意味着要对表达式进行解析,以便将较高优先级运算的结果用于较低优先级运算中,而不是相反。仅在需要时才对实际表达式求值!
您正在混淆两个相关但不同的主题:运算符优先级和评估顺序。
运算符优先级规则规定了如何将各种运算符组合在一起。对于此表达式:
a=0 && --b;
运算符按如下方式分组:
a = (0 && (--b));
然而,这对操作数的求值顺序没有影响。&&
运算符特别要求首先对左操作数求值,如果其求值为0,则不对右操作数求值。
因此,在这种情况下,&&
的左侧为0
,因此,由于其值为0,因此不评估--b
的右侧,因此b
不递增。
这与优先级无关。该表达式从左到右求值。
a = 0
的值为false
,因此无需评估表达式的第二部分,因为false && true
为false
,给定表达式的第一部分为false
,则表达式将始终为[ C0],如果您有false
运算符,则必须对表达式的第二部分求值。