逻辑运算符与按位运算符的关键点是什么?
鉴于此声明是一个逻辑操作
((a > 5) && (b > 4))
这句话是按位操作的
((a > 5) & (b > 4))
以上两个陈述并不等同。
因为(a > 5)
是{0,1}
的元素
那么,为什么我们需要logical operators & bitwise-operation
?
编辑 :感谢所有的反馈。 关于逻辑运算符的短路行为,我实际上不希望这种行为 – 我正在为GPU编写代码,其中分支会降低性能:短路导致两个分支而不是代码中的一个分支。
对于C中的数值比较,在不需要短路的情况下,似乎逻辑和按位具有相同的行为。 在我的例子中,按位运算比逻辑快。
我为没有将这些细节放在原始post中而道歉。
我想不,拿这个例子(0b – 表示二进制):
a = 0b00000010 b = 0b00000100
现在, a
和b
都不是0.但是a & b == 0
(由于定义了按位AND的方式)。
但是a && b != 0
(因为如果至少有一个操作数是0,则逻辑AND结果为0 – 上面的a
和b
不是这种情况)。
还有短路评估,如果在&&
左操作数为0,则不会评估正确的一个,因为结果肯定是0(例如,如已经提到的0 && x == 0
无论x
值)。
- 逻辑运算符在组合它们之前将它们的操作数转换为
bool
,逻辑运算符的结果也一直是bool
。 按位运算符不会这样做(但是如果操作数是bool,那么这两种运算符之间没有区别)。 - 逻辑运算符可用于许多可转换为bool的操作数类型,而按位运算符仅在特定情况下的几种类型上工作,并且按位运算符的输出是键入的(并不总是bool)。
- 逻辑运算符是捷径。 例如,在
&&
情况下,这意味着:如果第一个操作数为假,则第二个操作数甚至不被评估,因为无论第二个操作数的值如何,整个表达式(false && something)都已为假。
逻辑快捷方式运算符经常在以下情况下被利用:
// If mypointer is NULL, then mypointer->is_whatever() // isn't evaluated so it doesn't cause a NULL pointer crash. if (mypointer && mypointer->is_whatever()) { // do my thing }
逻辑运算符是比较多个值的真实性。
例如,您使用&&
运算符来查看两个值是否都为true
。
逐位运算符用于隔离和修改值中的位。
例如,为了关闭除8之外的8位值中的所有位,您将执行以下操作:
val & 00100000
在上面的例子中,第6(基于1)或第5(基于0)位保持原样,其他位被关闭。
两种类型的运算符都相似,因为它们都产生0或1。
例如,拿这些:
1 || 0
上面会产生1
因为其中任何一个值都等于1
。 但是,如果我们将运算符切换为&&
,它将产生0。
在您尝试的所有运算符中,它们都将给出1
或0
, true
或false
。 那是因为之间没有:没有表达式评估为“真实排序”或“假冒伪劣”。
而且我认为逐位运算符总是“产生”1或0的原因是非常自我解释的:按位 ; 一点是1或0。
并非所有用作布尔值的表达式都评估为0或1; 虽然0被视为false,但0以外的任何值都被视为true。 因此,例如, 1 && 2
将是真的,但1 & 2
不会,即使1和2都被认为是真的。
另外,正如其他人所指出的那样,如果第一个表达式足以确定整体值(“短路”),逻辑运算符将不会评估第二个表达式,这显然不能用按位版本完成(好吧,不常见) ; 0 & ?
将为0,无论是什么?是,因此?不需要进行评估以获得最终值,但是&
不会那样工作)。