2012-02-22 39 views
5

我正在研究C的基础知识,并试图解决下面的问题,任何人都可以解释为什么变量c的输出是不同的?为什么c不会在输出中增加?

以下程序的输出是什么?

int main() 
{ 
    int a = -3, b = 2, c= 0, d; 
    d = ++a && ++b || ++c; 
    printf ("a = %d, b = %d, c = %d, d = %d", a, b, c, d); 
} 

答案:-2,3,0,1

c为什么没有在输出递增?

+1

d =((-2 && 3)||(++ C))。它在达到c之前短路。 – 2012-02-22 16:24:04

+0

你究竟在做什么?或者你只是简单地玩一些代码? – Bart 2012-02-22 16:25:27

+0

简单解决c谜题 – Nisha 2012-02-22 16:56:51

回答

10

变量c不会递增,因为||的RHS(右侧)不会被执行,除非LHS评估为假,并且LHS评估为真。 C ||&&运营商是'短路'运营商;他们不评估第二个操作数,除非第一个操作数不足以确定表达式的整体真值。

&&结合比||更紧,所以操作可以括号为:

d = (++a && ++b) || ++c; 

++a的值为-2,其评估为真(,因为这是不为0的任意值的计算结果为真); ++b的值为3,其结果为真;所以&&这个术语的值是真实的。由于true || falsetrue || true都评估为true,因此无需评估RHS以了解整体结果。 (&&的类似规则是,如果第一项评估为假,则不需要评估第二项,因为整体表达式必须是假的。如果在测试之前有a = -1;,则b不会递增,因为++a会因为&&的RHS是未评估的,当然,c会增加,因为||的LHS将是错误的,并且必须对RHS进行评估以确定总体结果。)

+2

也许他不明白-2和3如何评估为真。 – 2012-02-22 16:27:46

+0

@ 0A0D:我已经说过 - 你可能是对的。 – 2012-02-22 16:36:46

9

因为++a && ++b评估为true

这就是所谓的短路。条件内的表达式从左到右进行评估。如果您的情况,如果OR子句中的第一个条件评估为true,则没有必要对第二个条件进行评估,因为已知整个表达式为true

2

在C中,布尔逻辑运算符&&||short-circuiting。这意味着他们只评估他们的右侧,如果评估左侧还不足以知道答案。

对于您的代码,这样做的效果是从不评估++c,因为左侧不为零,因此布尔值或结果将为true,因此无需执行更多工作。

2

这是懒惰的布尔表达式评估。 执行是:

++a-2

++b3

-2 && 31

好吧!无需检查||的结果。因此++c未被评估。

规则是:表达式部分X在下列情况下不进行评估:(0 && X),(1 || X)。当然这里1是“不是0”。

2
 
d= ++a && ++b || ++c 
d= ++(-2) && ++b || ++c 
d= -1 && ++b || ++c 
d= true && ++b || ++c 
d= true && ++2 || ++c 
d= true && true || ++c 
d= true || ++c 
d= 1 

这就是它大致是如何工作的幕后...