16

为什么下面提到的程序的输出0不是20

#include <stdio.h>

int main()
{
    int i = 10, j = 0;
    if (i || (j = i + 10))
       /* do something */;                
    printf("%d\n",j);
}
4

4 回答 4

27

是的,这个概念被称为Short-Circuit(在逻辑&&,||运算符表达式中)。

对于任何逻辑表达式(包括||, &&),编译器会在结果评估后立即停止评估表达式(并保存执行)。

短路技术是:

!0 || any_expression== 1,所以any_expression不需要评估。

并且因为在你的表达式i中不是零而是它的 10,所以你可以认为 if 条件(i || (j = i + 10)) 就像i.

逻辑或运算符:运算符保证从左到右的求值
||在计算第一个操作数之后有一个序列点。如果第一个操作数与 比较unequal0not 计算第二个操作数。

&& (和运算符)类似:
0 && any_expression== 0,因此any_expression不需要评估。

在你的表达中:

(i || (j = i + 10) )
      ------------
       ^
       | Could evaluate if i is 0, 
       as i = 10 (!0 = true), so j remains unchanged as second operand is not evaluated

For or ||operator answer可以是 0、1。为了保存执行,一旦找到结果,评估就会停止。因此,如果第一个操作数非零1 ,则表达式的结果将是(如上)。因此,对于第一个操作数i = 10比较不等于 0,第二个操作数(j = i + 10)不会被评估,因此j仍然存在0,因此您的代码的输出是0.

注意:短路行为不仅存在于 C 中,而且概念对于 Java、C++、Python 等许多语言都很常见。(但不是全部,例如 VB6)。

在 C 中,保证逻辑表达式的短路一直是 C 的一个特性。当 Dennis Ritchie 设计和实现 C 的第一个版本时确实如此,在 1989 年的 C 标准中仍然如此,并且在 C99 标准中仍然如此。

相关帖子:C/C++ 中是否强制要求短路布尔运算符?和评价顺序?

于 2013-07-19T08:03:25.147 回答
20

||短路运算符 - 如果左侧计算结果为真,则不需要计算右侧。因此,在您的情况下,因为i为真,所以j = i + 10不评估表达式。但是,如果您设置为 0,则将评估i右侧,

于 2013-07-19T08:02:21.407 回答
5

if (i || (j = i + 10))中,有两个布尔表达式要计算。问题是,第一个是真的,因此不需要计算第二个。它完全被忽略了。

于 2013-07-19T08:04:00.750 回答
3

因为||是短路运算符(&&运算符也是)。

所以 in (i || j = i+10),i是 10, 左边部分||为真, 表达式j = i+10没有发生, 结果, j=0.

于 2013-07-19T08:15:31.423 回答