鉴于
int x=1,y=2,z;
你能解释为什么结果:
x && y || z
是1?
x && y = 1
x && y || z = 1
答案 0 :(得分:19)
x && y || z
相当于
(x && y) || z
如果x=1
和y=2
然后x&&y
为1 && 2
,true && true
为true
。
true || z
总是true
。 z
甚至没有被评估
答案 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;
}
由于x
和y
都固定为非零值,因此始终会命中第一个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)
这里有两个组成部分:
如果它帮助你记住,就数学运算符而言,||可以用加号“+”代替,它由2个条形和&&组成。可以用“。”代替。并且乘法优先于“+”: - )
在C ++和C中,当正在计算布尔表达式并且可以从某个术语逻辑推断结果时,不会评估以下术语: 虚假&& (expr2)为false且未对expr2进行求值。 真|| (expr3)为true且expr3未被评估。
我希望这有助于=)