为什么下面提到的程序的输出0
不是20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
为什么下面提到的程序的输出0
不是20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
是的,这个概念被称为Short-Circuit(在逻辑&&
,||
运算符表达式中)。
对于任何逻辑表达式(包括||
, &&
),编译器会在结果评估后立即停止评估表达式(并保存执行)。
短路技术是:
!0 || any_expression
== 1
,所以any_expression
不需要评估。
并且因为在你的表达式i
中不是零而是它的 10,所以你可以认为 if 条件(i || (j = i + 10))
就像i
.
逻辑或运算符:运算符保证从左到右的求值
;||
在计算第一个操作数之后有一个序列点。如果第一个操作数与 比较unequal
,0
则not
计算第二个操作数。
&& (和运算符)类似:
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 标准中仍然如此。
||
是短路运算符 - 如果左侧计算结果为真,则不需要计算右侧。因此,在您的情况下,因为i
为真,所以j = i + 10
不评估表达式。但是,如果您设置为 0,则将评估i
右侧,
在if (i || (j = i + 10))
中,有两个布尔表达式要计算。问题是,第一个是真的,因此不需要计算第二个。它完全被忽略了。
因为||
是短路运算符(&&
运算符也是)。
所以 in (i || j = i+10)
,i
是 10, 左边部分||
为真, 表达式j = i+10
没有发生, 结果, j=0
.