&&和&&和&与bool(s)?

时间:2011-07-05 02:24:46

标签: c++ bitwise-operators boolean logical-operators language-lawyer

在C ++中,在bool(s)之间执行&&(逻辑)和&(按位)之间有什么区别吗?

bool val1 = foo();
bool val2 = bar();

bool case1 = val1 & val2;
bool case2 = val1 && val2;

case1case2是否完全相同,或者如果不相同,为什么会选择一个而不是另一个?是便宜的和bools便携式吗?

7 个答案:

答案 0 :(得分:37)

standard保证false转换为零,true转换为1作为整数:

  

4.7整体转换

     

...

     

如果目的地类型是bool,请参阅4.12。如果源类型为bool,则将值false转换为零,将值true转换为一个。

因此,您提供的示例中的效果保证相同,并且100%便携。

对于您提供的情况,任何体面的编译器都可能生成相同的(最佳)代码。

但是,对于布尔表达式expr1expr2,通常expr1 && expr2expr1 & expr2相同,因为&&执行“短” - 电路“评估。也就是说,如果expr1评估为false,则expr2甚至不会被评估。这可能会影响性能(如果expr2很复杂)和行为(如果expr2有副作用)。 (但请注意,&形式实际上可以更快,如果它避免了条件分支...出于性能原因而对这类事物进行操作几乎总是一个坏主意。)

因此,对于您给出的具体示例,您将值加载到局部变量中然后对它们进行操作,行为是相同的,并且很可能是性能。

在我看来,除非你特别依赖“短路”行为,否则你应该选择最明确表达你意图的表述。因此,对于逻辑AND使用&&,对于bit-twiddling AND使用&,并且任何有经验的C ++程序员都会发现您的代码很容易理解。

答案 1 :(得分:13)

使用逻辑和&&时,如果左侧表达式为false,则不会评估右侧表达式。

许多C / C ++ / C#代码依赖于此,如:if (p != null && p->Foo())

对于您的示例,我将使用case2(逻辑和)。在处理位标志等时只使用按位。

但是,如果foo()和bar()只返回bool(0,1),那么case1和case2是相同的。

答案 2 :(得分:8)

虽然你不会在你的例子中看到它,但是有一点不同(好吧,两个)。

“&安培;”执行按位“AND”操作,意味着0x1 & 0x1 = 0x1,但0x1 & 0x2 = 0x0。 OTOH,“&&”是一个布尔/逻辑“AND”,意味着它将任何非零值视为TRUE,因此0x1 && 0x1 = TRUE(通常表示为-1,即所有1 [或者它在C ++中表示为1,我忘了]),同时0x1 && 0x2 = TRUE

此外,“&&”是短路的,这意味着如果第一个操作数为FALSE,则不会评估第二个操作数。因此,FALSE & null_pointer->booleanField ==> null pointer exceptionFALSE && null_pointer->booleanField = FALSE

在某些情况下使用按位运算可能会有轻微的性能优势,但通常在评估布尔值时应使用double形式,以便您的代码独立于布尔值TRUE和FALSE的精确表示。

答案 3 :(得分:4)

在算法上没有区别,但使用&&允许您“检查”“短路”。也就是说,要判断case2,如果val1为false,那么编译后的代码没有理由检查val2的值以确定答案,其中case1需要实际的AND。

实际上,一个好的编译器会认识到这一点并生成相同的代码......这取决于你的编译器有多好。

答案 4 :(得分:2)

&& ”是“条件逻辑”AND“ 它仅在第一个表达式为TRUE

时才计算第二个表达式

& ”是“非条件逻辑AND”< - (如果您正在使用布尔表达式) 它评估两个表达式


<强>此外 “&安培;”是一个“按位”运算符,意味着它在位级操作。

这个例子可以让你更好地理解。

4 = 00000100  // 'four' bit set
5 = 00000101  // 'four' bit and 'one' bit set

00000100 (4) & // AND: only keep bits set in both
00000101 (5)
--------
00000100 (4)

00000100 (4) | // OR: keep bits set in either
00000101 (5)
--------
00000101 (5)

00000100 (4) ^ //  EXCLUSIVE OR: keep bits only set in one but not the other
00000101 (5)
--------
00000001 (1)

答案 5 :(得分:0)

逻辑运营商&amp;&amp;和||在评估两个表达式以获得单个关系结果时使用。运营商&amp;&amp;对应于布尔逻辑运算AND。如果两个操作数都为真,则此操作结果为true,否则为false。

运营商||对应于布尔逻辑运算OR。如果两个操作数中的任何一个为真,则此操作结果为true,因此仅当两个操作数都为假时才为假。

答案 6 :(得分:-2)

int a = 0, b = 10;

if(a == 1 && (b/a) == 0) cout << "This is okay\n"; // the 2nd expression is never checked as the first one is false

cout << "Bingo\n";

if(a == 1 & (b/a) == 0) cout << "This is not okay\n"; // program crashes here trying to divide by zero

cout << "Bingo\n"; // this will never get printed