-4

在书中,这里给出了递增和递减运算符的优先级大于三元运算符,但是为什么在下面的代码中,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

4 回答 4

4

条件 ( ?:)、逻辑合取 ( &&) 和逻辑析取 ( ||) 运算符是惰性的。它们只评估产生结果所需的操作数。

在条件运算符的情况下,它只计算两个分支之一;如果条件评估为真,则为第一个,如果条件评估为假,则为第二个。

如果左侧表达式的计算结果为假,则逻辑连接运算符将不会计算右侧表达式,因为无论如何结果都将为假。逻辑析取运算符以类似的方式运行,不同之处在于如果左侧评估为真,它将不会评估右侧:true || x始终为真,无论x.


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

于 2013-07-15T12:08:40.323 回答
2

参见C11 6.5.15 条件运算符 p4h = (a==1)?++b:++c; (我的重点

评估第一个操作数;在它的求值和第二个或第三个操作数的求值之间有一个序列点(以求值者为准)。仅当第一个比较不等于 0 时才计算第二个操作数;仅当第一个比较等于 0 时才评估第三个操作数

这证实了您观察到只有一个++b++c被执行是正确的。

参见++i&&++j||++k;C11 第 6.5.13、6.5.14 节。逻辑 OR 和 AND 运算符都从左到右求值,一旦知道结果,就跳过进一步的表达式求值(因此,一旦表达式求值为 非零||;一旦表达式求值为 0 &&)。

于 2013-07-15T12:07:44.970 回答
1

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

在第二种情况下,并不是所有的操作数都被计算,因为||and&&操作符做了所谓的“短路”,也就是说,如果整个表达式没有机会再改变它的结果,剩下的操作数不评价。

于 2013-07-15T12:07:52.913 回答
0

优先级不控制评估顺序。. 它只控制运算符和操作数如何组合在一起。

||和运算符都&&强制从左到右求值,并且都是“短路”运算符;如果表达式的值可以从左边的表达式中确定,那么右边的表达式根本不会被计算。

所以给定一个表达式

a++ || b++ && c++

如果 的结果a++不为零,则无论 的结果如何,结果都将为真b++ && c++,因此根本不计算右侧。

于 2013-07-15T14:28:19.587 回答