[英]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=1
且y=2
則x&&y
為1 && 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;
}
由於x
和y
都固定為非零值,因此始終會命中第一個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個組件:
如果它幫助你記住,就數學運算符而言,|| 可以用加號“+”代替,它由2個條組成,而&&可以用“。”代替。 並且乘法優先於“+”:-)
在C ++和C中,當正在計算布爾表達式並且可以從某個術語邏輯推斷結果時,不會評估以下術語:false &&(expr2)為false並且不會對expr2進行求值。 真|| (expr3)為true且expr3未被評估。
我希望這有助於=)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.