&&和&与bool(s)之间有什么区别吗?

Wil*_*mKF 31 c++ boolean bitwise-operators logical-operators language-lawyer

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

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

bool case1 = val1 & val2;
bool case2 = val1 && val2;
Run Code Online (Sandbox Code Playgroud)

case1case2相同或如果不究竟如何他们有所不同,为什么会选择一个一个比其他?是一个按位和bools便携式?

Nem*_*emo 38

标准保证了false转换到零,true转换成一个为整数:

4.7完整转换

...

如果目标类型是bool,请参见4.12.如果源类型为bool,则将值false转换为零,将值true转换为一.

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

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

然而,对于布尔表达式expr1expr2,它不是一般的事实,expr1 && expr2是一样的expr1 & expr2,因为&&执行"短路"的评价.也就是说,如果expr1评估false,expr2甚至不会评估.这可能会影响性能(如果expr2很复杂)和行为(如果expr2有副作用).(但请注意,&如果它避免使用条件分支,那么表单实际上可以更快...出于性能原因而玩这种东西几乎总是一个坏主意.)

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

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

  • @PatrickT:是的,出于同样的原因.("OR"和"AND"是双重操作;也就是说,如果你将"OR"与"AND"和"false"交换为"true",所有方程式仍然成立.换句话说,OR和AND实际上是相同的操作,只是生活在积极逻辑和消极逻辑世界.它们在C/C++中的实现尊重这种相似性,这被称为"De Morgan定律".) (3认同)

Ric*_*der 13

使用logical时&&,如果左侧表达式为false,则不会评估右侧表达式.

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

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

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


Hot*_*cks 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 exception,FALSE && null_pointer->booleanField = FALSE.

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


小智 5

&& ”是一个“条件逻辑“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)
Run Code Online (Sandbox Code Playgroud)