关系运算符会影响赋值运算符操作吗?

dus*_*abo 16 c

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

#include <stdio.h>

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

Gri*_*han 27

是的,这个概念叫做短路(逻辑上&&,||运算符表达式).

在任何逻辑表达式(包括||,&&)的情况下,编译器一旦结果评估就停止评估表达式(并保存执行).

短路技术是:

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

而且因为在你的表达i是不为零,但其10,所以你可以认为如果consdition (i || (j = i + 10)) 一样i.

逻辑OR运算符:
||运营商保证左到右的评价; 在评估第一个操作数后有一个序列点.如果第一操作数进行比较unequal0,第二个操作数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
Run Code Online (Sandbox Code Playgroud)

对于或||操作员的回答可以是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++中强制要求短路布尔运算符吗?和评估顺序?

  • 老实说,答案太长了. (9认同)
  • *"在任何一个逻辑表达式大多数编译器停止评价表述的情况下,一旦评估结果(以节省执行)."* - 不,它不是由*"大多数编译器"*完成的,而是由*所有*该呼叫他们自己是C编译器,因为它是由标准强制执行的.因此,更多的往往不是这不只是为了性能,但正确性,例如着想想想`而(节点&&节点 - >值)`,如果标准没有*保证*短cirtuiting这将是可怕的错误. (9认同)
  • @GrijeshChauhan你可能不同意这一点(只有标准的comitte可以回答这个问题,你可能对原始目的很正确).但是,你绝对不能不同意不是"大多数编译器"*这样做,而是*全部*.不执行此操作的编译器不是C编译器,它就像`=`或`+`这样的东西不会按预期工作,你不能依赖任何代码来使用这样的编译器.你可以回答一下这样的声音,这只是一个编译器实现优化,而不是*的情况. (7认同)
  • @Grijesh:你只需要澄清这句话,这样人们在阅读你的答案时就不会有错误的想法.你可以看到已经有两个人误解了你的答案.关于SO的一个好处就是答案总能被*改进*. (4认同)
  • 谢谢,它不再是误导,+ 2. (2认同)

Pau*_*l R 20

||短路操作符 - 如果左侧评估为真,则不需要评估右侧.因此,在您的情况下,因为i是真的,所以j = i + 10不评估表达式.如果设置i为0,则会评估右侧,

  • @TheJoker不,在C短路的逻辑表达式保证一直是C的一个特征. (3认同)

joh*_*n d 5

if (i || (j = i + 10)),有两个布尔表达式来评估.问题是,第一个是真的,因此没有必要计算第二个.它完全被忽略了.