鉴于
int x=1,y=2,z;
能否解释一下为什么以下内容的结果是:
x && y || z
是1吗?
x && y = 1
x && y || z = 1
鉴于
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
=> 1 || z
=> 1
(bool)1 = true
(bool)2 = true
未初始化的整型是指保存在内存中的数据,通常放在栈上... 它很少是 0x00000000
,即使是这样,true || false = true
。
&&
运算符的优先级高于 ||
运算符。可以参考,例如,此运算符优先级表格,第 13 和 14 项。
你的示例被计算为 (x && y) || z
。由于短路规则,当 x && y
的结果为 true
时,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
都被固定为非零值,因此第一个返回语句总是被执行。
在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 技术所模糊),但是表达式 x && y || z
基本上消失了,因为编译器能够在编译时推断出其值。x && y
被解释为(x != 0) && (y != 0)
,这等同于1 && 1
,结果为1。而1 || 0
是1,无论y的值是多少。&& 运算符的优先级高于 || 运算符。
这里有两个组成部分:
如果它能帮助你记住,在数学运算符方面,|| 可以用加号 "+" 替换,它由 2 条杠组成;而 && 可以用 "." 替换,并且具有乘法的优先级大于 "+" :-)
在 C++ 和 C 中,当布尔表达式正在被评估并且结果可以从某个术语中逻辑地推断出来时,以下术语不会被评估:
false && (expr2) 是 false AND expr2 不会被评估。
true || (expr3) 是 true AND expr3 不会被评估。
希望这可以帮到你 =)