2013-10-26 40 views
3

在下面的代码:短路和在递增/递减操作者的情况下

#include <stdio.h> 

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

我期待的输出为:

A = 0,B = 1,C = 1 ,d = 0

因为由于在下面的行短路,即a--返回0所以其他部分将不会得到正确执行?

int d = a-- && --b; 

的输出是:

A = 0,B = 0,C = 1,d = 0

谁能请解释?

+1

'A - '计算结果为' a',在本例中为'1',然后递减'a'。 – godel9

回答

5
int c = a || --b; 

在此行中,C标准需要 C实现评估a第一,如果它不为零,不评价--b。尽管--||具有更高的优先级,但这仅仅意味着--b分组以用于确定表达式的结构,而不是用于评估它的目的。 ||运营商的左侧必须在右侧之前进行评估,如果左侧为真,则右侧不得即使部分评估。

所以,在上面之后,b没有改变;它仍然1.

int d = a-- && --b; 

是与||,所述&&的左手侧被第一评价。因此评估a--。这将a更改为0.但是,a--的值在更改前为a,因此它为1.值为0将阻止评估右侧(因为一旦我们知道左侧为零,我们就知道完整&&表达式的值为零)。但是,由于左侧不是零,因此必须评估--b以完成&&。这将b更改为0.“短路”意味着评估左侧第一个,但右侧仍在必要时评估。

+3

+1我认为我们在这里有一个完整和清晰的答案。 – Sadique

+0

是完整的答案。这真的很有意义 – niko

+0

是的 - 当我发布了我的答案 - 我完全忽略了这样一个事实,即有序列点在&&(逻辑与)的左和右操作数的评估之间, (逻辑或)(作为短路评估的一部分)和逗号运算符' – Sadique

-2

您在混合a----a。表达式a--的结果是a之前的递减量,而--aa之后的递减量;换句话说:

int a = 1; 
int b = a--; // b == a == 1 
int c = --b; // c == b-1 == 0 

其结果是,你必须:

int d = a-- && --b; 
// => 1 && b-1 
// => 1 && 0 
// => 0 
+0

在原始代码中没有'int b = a - ;',并且在原始代码中不对'c'的赋值评估'--b'。 –

+0

我并没有试图在那里复制他的代码。我认为这很明显,但有w/e。 –

5

在第一种情况下

int c = a || --b; 

这个a=1b=1c=1

a值之后为1 , 因为短路评价--b没有进行

int d = a-- && --b; 

a--post decrement所以a递减不会表达 效果,即作为--b在这里pre decrement所以效果

你的条件变得

int d= 1 && 0 ; 

此后a=0;,b=0,c=1d=0

+1

我不明白为什么你的答案是downvoted(我的答案相同)。所以,+1。 –

+0

感谢您的支持。我没有坦率地解释清楚。我被错误地解释了。 – Gangadhar

+3

@Maxime:它被拒绝了,因为它最初是错误的;它表示'--b'首先执行。从那以后它一直在编辑。 –

2

下面的线,即a--返回0

不,不。它产生1,因为后减量运算符评估为未修改的变量值。你在想什么可能是--a

+0

第一次尝试'1 - po'让我感到困惑 –

+0

@GrijeshChauhan够公平的。我已经说过了。 – 2013-10-26 12:23:30

+1

你的回答并没有使我们满意..你能否做出更明确的解释 – niko

4

在第一操作,--b没有执行,因为a等于1:

int c = a || --b; 

b这里递减:

int d = a-- && --b; 

因为a等于1,之后递减评估(a--等于1)。换句话说,这条线是类似于:

int d = 1 && --b; 

b等于1所以现在b等于0现在。而d也等于0,因为--b返回0

+0

你能告诉我为什么b仍然是0为什么不转为-1? 。 – niko

+0

@nico b此时等于1。这就是为什么。我会编辑以解释上一行。 –

1
c = a || --b

所以在第一a is evaluateda值为1这是true。所以编译器不会评估--b。所以b值仍然1

现在

d = a-- && --b

a-- && --b =>1 && 0(自--b = 0)因为b值为1

为什么1 because a-- is post decrement operator

为什么0 because --b is pre decrement operator

所以1 & & 0返回0,这个值被保存在d

所以输出:a = 0, b = 0, c = 1, d = 0

+0

这里没有关联性。从左到右的相关性意味着'a || b || c'被分组为'(a‖b)|| C'。这并不意味着'a'在'b'之前被评估。这是一个单独的规则。 –