在递增/递减运算符的情况下AND的短路

时间:2013-10-26 12:13:17

标签: c logical-operators short-circuiting

在下面的代码中:

#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

任何人都可以解释一下吗?

6 个答案:

答案 0 :(得分:5)

在第一种情况下

int c = a || --b;  

此后a=1b=1c=1

a值为1,因为短路评估--b没有执行

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

a--post decrement因此a的减量不会影响表达式 其中--bpre decrement,因此效果

您的情况变为

   int d= 1 && 0 ; 

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

答案 1 :(得分:4)

在第一个操作中,由于--b等于1,因此a未执行:

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。

答案 2 :(得分:4)

int c = a || --b;

在这一行中,C标准要求 C实现首先评估a,如果不是零,不评估 {{1 }}。虽然--b的优先级高于--,但这只是意味着||--分组以确定表达式的结构,而不是为了评估它的目的。 b运算符的左侧必须在右侧之前进行评估,如果左侧为true,则右侧不得进行评估,甚至在一部分。

因此,在上述之后,||没有改变;它仍然是1。

b

int d = a-- && --b; 一样,首先评估||的左侧。因此评估&&。这会将a--更改为0.但是,更改前a的值为a--,因此它为1.值为0会阻止评估右侧(因为,一旦我们知道左侧为零,我们就知道完整a表达式的值为零)。但是,由于左侧不为零,因此必须评估&&以完成--b。这会将&&更改为0.“短路”表示左侧的评估优先,但仍会在必要时评估右侧。

答案 3 :(得分:2)

  

下面一行,即a--返回0

不,它没有。它产生1,因为后递减运算符计算变量的未修改值。您的想法可能是--a

答案 4 :(得分:1)

c = a || --b

因此,首先a is evaluateda值为1,即true。所以编译器不评估--b。因此b值仍为1

现在

d = a-- && --b

a-- && --b =&gt; 1 && 0 {自--b = 0)以来b值为1

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

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

所以1&amp;&amp; 0返回0,该值存储在d

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

答案 5 :(得分:-2)

您将a----a混为一谈。表达式a--的结果是{/ 1}} 减量之前,而a--a 之后减量;换句话说:

a

结果,你有:

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