2013-07-15 69 views
-3

在书中和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 

的语句解释一下,如果我做一些概念性的错误,使其对所对不起Ø小白 (如果这是一个重复的,那么请重定向我原来的问题,我没有找到一个)

+15

那么,我希望这种混乱可以成为像这样编写代码的强大威慑力量。 –

+4

哦,“过于本地化”,你去哪里了? :( – 2013-07-15 12:06:37

+0

@sumitb您是否清楚了解三元运算符的作用? – Nbr44

回答

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

三元运算符仅评估的条件操作数出现这种情况是真实的操作数。您的案例中的++c部分根本没有评估。

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

4

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

在条件操作的情况下,其仅计算两个分支中的一个;第一个如果条件评估为真,或第二个如果条件评估为假。如果左侧表达式的值为false,因为其结果将是错误的,不管是什么

逻辑连词操作不会评估右侧表达。逻辑分离操作符以相似的方式操作,不同之处在于,如果左侧评估为真,则不会评估右侧:true || x始终为真,无论x如何。


†除非您正在处理超载&&||。重载的操作符不能执行操作数的懒惰评估。

+0

@ShafikYaghmour从来没有发生过,它从来没有评估过这两个分支 –

+0

啊,条件运算符不能重载,所以不适用,我会重新编写它 –

+0

+1现在已经很清楚了。 –

0

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

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

所以赋予相同

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

表达式如果a++结果为非零,那么结果将是真不管b++ && c++结果,所以右侧不评估在所有。