2012-05-03 108 views
3

这个C程序的输出应该是什么?以下C程序的输出

#include<stdio.h> 
int main(){ 
    int x,y,z; 
    x=y=z=1; 
    z = ++x || ++y && ++z; 
    printf("x=%d y=%d z=%d\n",x,y,z); 
    return 0; 
} 

给定输出是: X = 2 Y = 1个,Z = 1
我明白x的输出,但看不到ž如何y和值没有得到增加。

回答

12

这是short-circuit evaluation的结果。

表达++x计算结果为2,以及编译器知道2 || anything始终计算为1(“真”),不管是什么anything是。因此,它不会继续评估anything,并且yz的值不会更改。

如果用

x=-1; 
y=z=1; 

尝试你会看到yz递增,因为编译器必须评估OR的右手边,以确定表达式的结果。

编辑: asaerl首先在评论中回答您的后续问题,所以我会稍微扩展他的正确答案。

运算符优先级决定组成表达式的各部分如何结合在一起。由于与具有小于或更高的优先级,编译器知道你写

++x || (++y && ++z) 

代替

(++x || ++y) && ++z 

这使得其任务是做一个或++x++y && ++z之间。在这一点上,通常可以自由选择是否会首选评估一个或另一个表达式 - 按照标​​准 - 您通常无法依赖特定顺序。该顺序与运营商优先级无关。

然而,专为||&&标准要求该评估将总是从左到右前进,使短路可以工作和开发人员可以上不被评估的RHS表达取决于如果评估的结果lhs告诉。

+1

感谢帮助,但不是优先顺序在这里发挥作用?含义++ y && ++ z应首先在||之前进行评估? – krishnang

+4

编号优先级是解析顺序,而不是评估顺序。 顺便说一句,如果'++ z'被评估过,那就是UB。 (改变'z'两次) – asaelr

1

在C中,除0以外的任何东西都被视为true,并且对于||的评估。从左到右。

因此,编译器将检查第一个左操作数,如果它是真的,那么编译器将不检查其他操作数。 ex。 A || B - 在这种情况下,如果A为真,那么编译器将只返回真,并且不会检查B是真还是假。但是,如果A为假,那么它将检查B并相应地返回,如果B为真则返回true,或者如果B为假,那么它将返回假。

在你的程序中,编译器首先会检查++ x(即2),而C中除0以外的任何内容都是真的,因此它不会检查/增加其他表达式。