在书中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
请解释我是否犯了一些概念上的错误而且抱歉太过于教练 (如果这是重复,那么请将我重定向到原始问题,我没有找到一个)
答案 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++
的结果如何,结果都将为真,因此根本不评估右侧。