bool x = false, y = false, z = true;
if(x || y || z){}
or
if(x | y | z){}
第二个 if 语句是否对所有布尔值执行有点明智的“或”操作?把它们当作有字节来对待?例如)(0000 | 0000 | 0001)= 真...
还是它的行为像 Java | 在布尔值上,即使第一个为真,它也会评估表达式中的每个布尔值?
我想知道按位运算符如何处理布尔值。它是否等同于整数按位运算?
bool x = false, y = false, z = true;
if(x || y || z){}
or
if(x | y | z){}
第二个 if 语句是否对所有布尔值执行有点明智的“或”操作?把它们当作有字节来对待?例如)(0000 | 0000 | 0001)= 真...
还是它的行为像 Java | 在布尔值上,即使第一个为真,它也会评估表达式中的每个布尔值?
我想知道按位运算符如何处理布尔值。它是否等同于整数按位运算?
效率取决于,逻辑 or 运算符||
是短路运算符,这意味着如果x
在您的示例中为真,它将不会评估y
or z
。如果它是一个逻辑&&
然后如果x
是假的,它不会测试y
or z
。重要的是要注意,此操作不作为指令存在,因此您必须使用测试和跳转指令。这意味着分支,这会减慢速度。由于现代 CPU 是流水线的。
但真正的答案是视情况而定,就像许多其他这种性质的问题一样,有时短路操作的好处超过了成本。
在以下极其简单的示例中,您可以看到按位 or|
更好。
#include <iostream>
bool test1(bool a, bool b, bool c)
{
return a | b | c;
}
bool test2(bool a, bool b, bool c)
{
return a || b || c;
}
int main()
{
bool a = true;
bool b = false;
bool c = true;
test1(a,b,c);
test2(a,b,c);
return 0;
}
以下是由 gcc-4.8 生成的 intel 样式的程序集列表,其中-O3
:
test1
程序集:
_Z5test1bbb:
.LFB1264:
.cfi_startproc
mov eax, edx
or eax, esi
or eax, edi
ret
.cfi_endproc
test2
部件 :
_Z5test2bbb:
.LFB1265:
.cfi_startproc
test dil, dil
jne .L6
test sil, sil
mov eax, edx
jne .L6
rep; ret
.p2align 4,,10
.p2align 3
.L6:
mov eax, 1
ret
.cfi_endproc
你可以看到它有分支指令,这会弄乱管道。
但有时短路是值得的,例如
return x && deep_recursion_function();
免责声明:
我总是在bools
. 除非性能真的很关键,或者可能是简单的情况,比如 in test1
andtest2
但有很多布尔值。在任何一种情况下,首先验证您确实得到了改进。
第二幕java | 在整数上,按位或。由于 C 最初没有布尔类型,if 语句读取任何非零为真,因此您可以使用它,但使用短路运算符 || 通常更有效 相反,尤其是在调用返回条件的函数时。
我还想指出,短路可以让您检查不安全的条件,例如if(myptr == NULL || myptr->struct_member < 0) return -1;
,在使用按位或当 myptr为空时会给您一个段错误。