C的短路评估

时间:2017-08-23 20:35:54

标签: c operators logical-operators short-circuiting

我是在Kelley-Pohl的C书上学习C,而且这个练习我不明白:

int a = 0, b = 0, x;

x = 0 && (a = b = 777);
printf("%d %d %d\n", a, b, x);
x = 777 || (a = ++b);
printf("%d %d %d\n", a, b, x);

他们只是说想象输出并将其与真实的输出进行比较。我以为输出会是

  

777 777 0

     

778 778 1

但它是

  

0 0 0

     

0 0 1

2 个答案:

答案 0 :(得分:4)

&&运算符使用lazy evaluation。如果&&运算符的任一侧为false,则整个表达式为false

C检查运算符左侧的真值,在您的情况下为0。由于0在c中为false,因此操作的右侧表达式(a = b = 777)永远不会被评估。

第二种情况类似,只是如果左侧表达式返回||,则true返回true。另请注意,在c中,任何非0的内容都被视为true

希望这有帮助。

答案 1 :(得分:4)

来自C标准(6.5.13逻辑AND运算符)

  

3&&如果两个操作数都比较,则运算符产生1   不等于0;否则,它会产生0 。结果的类型为int。

  

4与按位二进制&操作员,&&运营商保证   从左到右的评价;如果评估第二个操作数,则有   第一个和第二个的评估之间的序列点   操作数。 如果第一个操作数比较等于0,则第二个操作数   操作数未被评估。

在此表达式声明中

x = 0 && (a = b = 777);

第一个操作数比较等于0.因此,不计算第二个操作数,即变量ab的值不会更改。因此,根据该部分的第3段,变量x将设置为0

来自C标准(6.5.14逻辑OR运算符)

  

3 ||如果任一操作数进行比较,则运算符将产生1   不等于0;否则,它会产生0。结果的类型为int。

  

4与按位|不同运算符,||运营商保证   从左到右的评价;如果评估第二个操作数,则有   第一个和第二个的评估之间的序列点   操作数。我 f第一个操作数比较不等于0,第二个操作数   操作数未被评估。

在此表达式声明中

x = 777 || (a = ++b);

第一个操作数比较不等于0.所以不计算第二个操作数,即变量ab的值没有改变。所以变量x将根据本节第3段设置为1

如果要更改

等表达式中操作数的顺序
x = (a = b = 777) && 0;
x = (a = ++b) || 777;

你得到了你期望的结果。