为什么下面提到的程序的输出是0
而不是20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
答案 0 :(得分:27)
是的,该概念称为Short-Circuit(在逻辑&&
,||
运算符表达式中)。
对于任何逻辑表达式(包括||
,&&
)编译器,一旦结果评估(并保存执行),就停止评估表达式。
短路技术是:
!0 || any_expression
== 1
,因此any_expression
无需评估。
因为在你的表达中,i
不是零,而是10,所以你可以考虑将(i || (j = i + 10))
作为i
。
逻辑OR运算符:
||
运算符保证从左到右的评估;有一个 评估第一个操作数后的序列点。如果是第一个 操作数将unequal
与0
进行比较,第二个操作数为not
评价。
同样适用于&amp;&amp; (和经营者):
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
对于或||
运算符的回答可以是0,1。为了保存执行,只要结果找到,评估就会停止。因此,如果第一个操作数为非零,则表达式的结果为1
(如上所示)。因此,对于第一个操作数i = 10
比较不等于0,第二个操作数(j = i + 10)
未被评估,因此j
仍为0
,因此您的代码输出为0
。< / p>
注意:短路行为不仅存在于C中,而且概念在Java,C ++,Python等许多语言中都很常见。 (但不是全部,例如VB6)。
在C中,逻辑表达式的短路保证一直是C的一个特征。当Dennis Ritchie设计并实现了C的第一个版本时仍然如此,在1989 C标准中仍然如此,并且在C99中仍然如此标准。
相关帖子:Is short-circuiting boolean operators mandated in C/C++? And evaluation order?
答案 1 :(得分:20)
||
是short-circuit运算符 - 如果左侧评估为true,则不需要评估右侧。因此,在您的情况下,由于i
为真,因此不评估表达式j = i + 10
。如果您将i
设置为0,则会评估右侧 ,
答案 2 :(得分:5)
在if (i || (j = i + 10))
中,有两个布尔表达式要评估。问题是,第一个是真的,因此没有必要计算第二个。它完全被忽略了。
答案 3 :(得分:3)
因为||
是一个短路运算符(&&
运算符也是如此)。
所以在(i || j = i+10)
,i
为10,||
的左侧部分为真,表达式j = i+10
没有发生,因此j=0
1}}。