簡體   English   中英

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

[英]how is x&&y||z evaluated?

特定

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 

總是true z甚至沒有評估

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未被評估。

我希望這有助於=)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM