x && y || z如何评估?

特定

int x=1,y=2,z; 

你能解释一下为什么结果:

 x && y || z 

是1?

 x && y = 1 x && y || z = 1 

 x && y || z 

相当于

 (x && y) || z 

如果x=1y=2x&&y1 && 2 ,这是true && true ,这是true

 true || z 

总是truez甚至没有评估

x && y || z x && y || z => (x && y) || z (x && y) || z => 1 || z 1 || z => 1

 (bool)1 = true (bool)2 = true 

未初始化的int指的是保存在内存中的数据,它放在堆栈中…而且很少是0x00000000 ,即使它是true || false = true true || false = true

&&运算符的优先级高于|| 运营商。 例如,参见此运算符优先级表 ,数字13和14。

您的示例评估为(x && y) || z (x && y) || z 。 由于短路规则, z永远不会被评估,因为x && y的结果已经是true

你可以想到x && y || z x && y || z等同于:

 int func(int x, int y, int z) { if (x) { if (y) { return true; } } if (z) { return true; } return false; } 

由于xy都固定为非零值,因此始终会命中第一个return语句。

在IA32上,没有优化x && y || z x && y || z成为:

  movl $1, 28(%esp) ; store 1 in x (on stack) movl $2, 24(%esp) ; store 2 in y (on stack) cmpl $0, 28(%esp) ; compare x to 0 je .L6 ; if x is 0 jump to L6 cmpl $0, 24(%esp) ; compare y to 0 jne .L7 ; if y is 0 jump to L7 .L6: ; We only get to L6 if (x && y) was false cmpl $0, 20(%esp) ; compare z to 0 je .L8 ; if z is 0 jump to L8 .L7: ; We get to this label if either (x && y) was true ; or z was true movl $1, %eax ; copy 1 into register eax, the result jmp .L9 ; jump unconditionally to L9 .L8: ; We only get here if both (x && y) and z are false movl $0, %eax ; copy 0 into register eax, the result .L9: 

并且func变成:

  cmpl $0, 8(%ebp) ; compare first argument (x) with 0 je .L2 ; jump to L2 if it is cmpl $0, 12(%ebp) ; compare second argument (y) with 0 je .L2 ; jump to L2 if it is movl $1, %eax ; store 1 for the return value (via register eax) jmp .L3 ; jump to L3 (done, return to caller) .L2: ; if we hit this label both x and y were false cmpl $0, 16(%ebp) ; compare third argument (z) with 0 je .L4 ; if it is 0 jump to L4 movl $1, %eax ; store 1 in register eax, which is the return value jmp .L3 ; jump to L3 (return to caller) .L4: ; if we get here x, y and z were all 0 movl $0, %eax ; store 0 in eax to return false .L3: 

在启用优化的情况下, func()看起来更像表达式(返回值仅从一个地方加载,尽管它被x86-isms遮盖),但表达式x && y || z x && y || z基本上消失了,因为编译器能够在编译时推断出它的值。

因为x && y被评估为(x != 0) && (y != 0) ,这相当于1 && 1得到1.和1 || 0 1 || 0是1,无论y值是多少。

&&运算符的优先级高于|| 操作者

这里有2个组件:

  1. 优先权
  2. 短电路

如果它帮助你记住,就数学运算符而言,|| 可以用加号“+”代替,它由2个条组成,而&&可以用“。”代替。 并且乘法优先于“+”:-)

在C ++和C中,当正在计算布尔表达式并且可以从某个术语逻辑推断结果时,不会评估以下术语:false &&(expr2)为false且expr2未得到评估。 真|| (expr3)为true且未对expr3进行求值。

我希望这有助于=)