2
#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操作的总体结果为true或1。但是,由于使用了短路逻辑或,所以第二个括号没有得到评估。

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

编辑: 我问是this(建议一式两份)有所不同 因为我在封闭的第二个操作数OR运算括号强调。

+0

请注意,如果第一个括号表达式为真,则短路评估不会消除“(l ++)”*或其副作用*。括号没有什么区别,'(l ++)'和'l ++' –

+0

...一样,第一部分类似:如果'i == 0',那么接下来的两个表达式不会被评估,效果'j ++'和'k ++'不会发生。这是编写代码的危险方式! –

+1

[在C语言中使用++运算符对语句进行短路评估]的可能重复(http://stackoverflow.com/questions/31779410/short-circuit-evaluation-of-a-statement-with-operator-in-c ) –

回答

2

运算符优先级(和关联性)只决定如何解析表达式。将它与的操作数评估顺序混淆是一种常见的错误,这是不同的事情。在这个例子中,运算符优先级是无关紧要的。

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

4

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

在这种情况下,规格很清楚。

||经营者应当得到1如果任一操作数的比较不等于0;否则,它产生。结果为int

和,(重点煤矿

不同的是按位|操作,||运营商保证左到右的评价;如果对第二个操作数进行求值,则在第一个操作数的第一个操作数和第二个操作数的评估之间有一个序列点。如果第一个操作数比较不等于0,则第二个操作数是 未评估。

在你的情况,

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

(i++ && j++ && k++)是左操作数和(l++);是正确的操作数,其余的应该是相当清楚的。 :)

+0

@Deniz非常正确,但这与优先级并不完全相关。这就是增量前后运算符的行为方式。 –