按位运算符处理位,逻辑运算符计算布尔表达式。只要表达式返回bool
,为什么我们不使用按位运算符而不是逻辑?
在这个例子中,我使用按位而不是逻辑:
#include <iostream>
int main(){
int age;
std::cin >> age;
if( (age < 0) | (age > 100) ) // eg: -50: 1 | 0 = 1
std::cout << "Invalid age!" << std::endl;
// if( (age < 0) || (age > 100) )
// std::cout << "Invalid age!" << std::endl;
return 0;
}
答案 0 :(得分:11)
一个可能的答案是:优化。例如:
if ((age < 0) | (age > 100))
假设age = -5
,无需评估(age > 100)
,因为满足第一个条件(-5<0
)。但是,前面的代码将评估(age > 100)
表达式,这是不必要的。
使用:
if ((age < 0) || (age > 100))
仅将评估第一部分。
注意:在评论中提及 @Lundin 时,由于第二次分支的准确性,有时|
比||
快选项(以及错误预测的问题)。因此,在其他表达式如此便宜的情况下,|选项 可能 更快。因此,在这些情况下了解的唯一方法是在目标平台上对代码进行基准测试。
最重要的答案是避免未定义的行为和错误:
你可以想象这段代码:
int* int_ptr = nullptr;
if ((int_ptr != nullptr) & (*int_ptr == 5))
此代码包含未定义的行为。但是,如果将&
替换为&&
,则不再存在未定义的行为。
答案 1 :(得分:2)
你不应该。假设您收到两个值,只有当它们都非零时才允许您继续。
b && c == true
以下条件导致以下情况:b & c == 0
,而if (b && c)
{
// This block will be entered
}
if (b & c)
{
// This block won't
}
"\n"
答案 2 :(得分:1)
即使您使用逐位运算符获得相同的结果,由于性能原因,最好在此处使用逻辑运算符。
在表达式(age < 0) || (age > 100)
中,仅当(age > 100)
为(age < 0)
时,才会计算第二个条件false
。对于这样的表达式,编译器生成如下代码:
cmpl $0x0,-0x4(%rbp)
js 1004010f9 <main+0x19> // <-- Skip right expr evaluation if left true
cmpl $0x64,-0x4(%rbp)
jle 100401100 <main+0x20>
||
不会产生任何额外的分支,以便能够跳过第二次表达式评估。
答案 3 :(得分:1)
||
和|
之间存在明显差异。
与该语言中的大多数其他运算符不同,逻辑||
运算符明确指定了评估顺序。必须在第二个之前评估||
的第一个操作数。第二个根本不需要评估。
这与作为大多数运算符的|
根本不同:评估顺序未指定,并且将评估两个表达式。即使在发现一个操作数非零的情况下,仍然会评估另一个操作数的副作用。
意味着像f1() || f2()
这样的代码将始终评估为此伪代码:
if(f1() != 0)
{
f2();
}
而f1() | f2()
将以程序员无法知道的未指定顺序执行这两个函数。
这也意味着像“||这样的语句比|”更快是天真的。当然,在||
的情况下,第二个操作数不一定被评估,但这是以分支为代价的,以及对如何允许编译器重新排序表达式的限制。通常更快的哪个运营商并不明显。
答案 4 :(得分:0)
答案是肯定的,你可以。问题是你为什么要这样做?我可以列举一些你不应该提出的理由:
bool
类型,这会导致细微的错误。说明最后一点:
bool f1() {
cout << "f1" << endl;
return true;
}
bool f2() {
cout << "f2" << endl;
return true;
}
int main() {
if (f1() || f2()) {
cout << "That was for ||" << endl;
}
if (f1() | f2()) {
cout << "That was for |" << endl;
}
return 0;
}
打印:
f1
That was for ||
f1
f2
That was for |
假设f2
可能有明显的副作用(if (okToDestroyWorld && destroyWorld()) ...
),差异可能很大。它不会让Java程序员感到惊讶(其中|
和||
实际上通过语言规范为布尔定义了),但这在C ++中并不常见。
我可以想到使用按位运算符进行布尔运算的一个原因:如果需要XOR。没有^^
运算符,只要if (a ^ b)
和a
都b
,bool
就可以了,并且不会产生任何副作用。