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

时间:2011-09-01 08:58:07

标签: c++ c operators expression

鉴于

int x=1,y=2,z;

你能解释为什么结果:

x && y || z 

是1?

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

8 个答案:

答案 0 :(得分:19)

x && y || z 

相当于

(x && y) || z

如果x=1y=2 然后x&&y1 && 2true && truetrue

true || z 

总是truez甚至没有被评估

答案 1 :(得分:6)

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:5)

&&运算符的优先级高于||运算符。例如,参见this operators precedence table,数字13和14。

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

答案 4 :(得分:4)

您可以将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变为:

        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基本上从编译器中消失能够在编译时推断出它的价值。

答案 5 :(得分:1)

因为x && y被评估为(x != 0) && (y != 0),因此与1 && 1相等,结果为1. 1 || 0为1,无论y值是多少。

答案 6 :(得分:0)

&& 运算符的优先级高于 || 运算符

答案 7 :(得分:0)

这里有两个组成部分:

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

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

    我希望这有助于=)