运算符优先顺序和评估混淆

时间:2013-07-15 12:02:59

标签: c++ c operators operator-precedence

在书中here给出了增量和优先权的优先顺序。递减运算符不仅仅是三元运算符,但为什么在下面的代码中,b和c的值都没有递增但只有b递增(或c递增就是条件为假)

int a=1,h;
h = (a==1)?++b:++c;
printf("%d%d",b,c);

甚至是

之类的陈述
++i&&++j||++k;   // why not all the increment and decrement operator executes first

请解释我是否犯了一些概念上的错误而且抱歉太过于教练 (如果这是重复,那么请将我重定向到原始问题,我没有找到一个)

4 个答案:

答案 0 :(得分:4)

条件(?:),逻辑连接(&&)和逻辑分离(||)运算符是惰性。它们只评估产生结果所需的操作数。

对于条件运算符,它只计算两个分支中的一个;如果条件的计算结果为true,则为第一个;如果条件的计算结果为false,则为第二个。

如果左侧表达式的计算结果为false,则逻辑conjuntion运算符将不会计算右侧表达式,因为无论如何结果都将为false。逻辑分离运算符以类似的方式运算,区别在于如果左侧评估为真,它将不会评估右侧:true || x始终为真,无论x


除非您正在处理过载的&&||。重载运算符无法对操作数执行惰性求值。

答案 1 :(得分:2)

对于h = (a==1)?++b:++c;,请参阅 C11 6.5.15条件运算符p4 (我的重点

  

评估第一个操作数;它之间有一个序列点   评估和评估第二或第三操作数   (以评估者为准)。 仅当第二个操作数被评估时才会被评估   首先比较不等于0;第三个操作数仅在以下情况下进行评估   第一个比较等于0 ;

这确认您的观察结果只有++b++c中的一个是正确的。

对于++i&&++j||++k;,参见C11第6.5.13,6.5.14节。逻辑OR和AND运算符从左到右进行求值,一旦结果已知就跳过对其他表达式的求值(因此,一旦表达式对||求值为非零;一旦表达式求值为{{1} }})。

答案 2 :(得分:1)

三元运算符仅计算条件操作数和恰好为真的操作数。您的案例中的++c部分根本没有评估。

在第二种情况下,并非所有操作数都被评估,因为||&&运算符执行所谓的“短路”,也就是说,如果整个表达式没有有机会再改变它的结果,其余的操作数都没有被评估。

答案 3 :(得分:0)

优先权不会控制评估顺序。。它仅控制运算符和操作数组合在一起的方式。

||&&运营商都强制进行从左到右的评估,两者都是“短路”运营商;如果可以从左侧表达式确定表达式的值,则根本不会评估右侧表达式。

所以给出了像

这样的表达式
a++ || b++ && c++

如果a++的结果不为零,那么无论b++ && c++的结果如何,结果都将为真,因此根本不评估右侧。