Visual Basic 中的逻辑运算符和位运算符
逻辑运算符会比较 Boolean
表达式并返回 Boolean
结果。 And
、Or
、AndAlso
、OrElse
和 Xor
运算符是二元的,因为它们采用两个操作数,而 Not
运算符是一元的,因为它采用单个操作数。 其中一些运算符还可对整数值执行位逻辑运算。
一元逻辑运算符
Not 运算符对 Boolean
表达式执行逻辑非运算。 它生成与其操作数相反的逻辑。 如果表达式的计算结果为 True
,则 Not
返回 False
;如果表达式的计算结果为 False
,则 Not
返回 True
。 下面的示例对此进行了演示。
Dim x, y As Boolean
x = Not 23 > 14
y = Not 23 > 67
' The preceding statements set x to False and y to True.
二元逻辑运算符
And 运算符对两个 Boolean
表达式执行逻辑与运算。 如果两个表达式的计算结果均为 True
,则 And
返回 True
。 如果两个表达式的计算结果都为 False
,则 And
返回 False
。
Or 运算符对两个 Boolean
表达式执行逻辑析取运算或逻辑包含运算。 如果任一表达式的计算结果为 True
,或者两者的计算结果均为 True
,则 Or
返回 True
。 如果两个表达式的计算结果都不是 True
,则 Or
返回 False
。
Xor 运算符对两个 Boolean
表达式执行逻辑异或运算。 如果恰好一个表达式的计算结果为 True
,而非两个都是,则 Xor
返回 True
。 如果两个表达式的计算结果均为 True
,或者均为 False
,则 Xor
返回 False
。
下面的示例演示 And
、Or
和 Xor
运算符。
Dim a, b, c, d, e, f, g As Boolean
a = 23 > 14 And 11 > 8
b = 14 > 23 And 11 > 8
' The preceding statements set a to True and b to False.
c = 23 > 14 Or 8 > 11
d = 23 > 67 Or 8 > 11
' The preceding statements set c to True and d to False.
e = 23 > 67 Xor 11 > 8
f = 23 > 14 Xor 11 > 8
g = 14 > 23 Xor 8 > 11
' The preceding statements set e to True, f to False, and g to False.
短路逻辑运算
AndAlso 运算符与 And
运算符非常类似,它也对两个 Boolean
表达式执行逻辑与运算。 这两者的主要区别在于 AndAlso
表现出短路行为。 如果 AndAlso
表达式中的第一个表达式的计算结果为 False
,则不会计算第二个表达式(因为它不能更改最终结果),并且 AndAlso
返回 False
。
同样,OrElse 运算符对两个 Boolean
表达式执行短路逻辑析取。 如果 OrElse
表达式中的第一个表达式的计算结果为 True
,则不会计算第二个表达式(因为它不能更改最终结果),并且 OrElse
返回 True
。
短路利弊分析
短路情况下不评估无法修改逻辑运算结果的表达式,因此可提高性能。 但是,如果该表达式执行其他操作,则短路将跳过这些操作。 例如,如果表达式包含对 Function
过程的调用,则在表达式短路时不会调用该过程,并且 Function
中包含的任何其他代码都不会运行。 因此,该函数可能仅偶尔运行,并且可能无法正确测试。 或者,程序逻辑可能依赖于 Function
中的代码。
下面的示例演示了 And
、Or
和其短路对应项之间的差异。
Dim amount As Integer = 12
Dim highestAllowed As Integer = 45
Dim grandTotal As Integer
If amount > highestAllowed And checkIfValid(amount) Then
' The preceding statement calls checkIfValid().
End If
If amount > highestAllowed AndAlso checkIfValid(amount) Then
' The preceding statement does not call checkIfValid().
End If
If amount < highestAllowed Or checkIfValid(amount) Then
' The preceding statement calls checkIfValid().
End If
If amount < highestAllowed OrElse checkIfValid(amount) Then
' The preceding statement does not call checkIfValid().
End If
Function checkIfValid(ByVal checkValue As Integer) As Boolean
If checkValue > 15 Then
MsgBox(CStr(checkValue) & " is not a valid value.")
' The MsgBox warning is not displayed if the call to
' checkIfValid() is part of a short-circuited expression.
Return False
Else
grandTotal += checkValue
' The grandTotal value is not updated if the call to
' checkIfValid() is part of a short-circuited expression.
Return True
End If
End Function
在前面的示例中,请注意,当调用短路时,checkIfValid()
中的一些重要代码不会运行。 由于 And
不会短路,因此即使 12 > 45
返回 False
,第一个 If
语句也会调用 checkIfValid()
。 第二个 If
语句不调用 checkIfValid()
,因为当 12 > 45
返回 False
时,AndAlso
会使第二个表达式短路。 由于 Or
不会短路,因此即使 12 < 45
返回 True
,第三个 If
语句也会调用 checkIfValid()
。 第四个 If
语句不调用 checkIfValid()
,因为当 12 < 45
返回 True
时,OrElse
会使第二个表达式短路。
位运算
位运算以二进制 (base 2) 形式计算两个整数值。 它们会比较相应位置上的位,然后根据比较结果来分配值。 下面的示例演示了 And
运算符。
Dim x As Integer
x = 3 And 5
前面的示例将 x
的值设置为 1。 出现这种情况的原因如下:
值被视为二进制值:
二进制格式的 3 = 011
二进制格式的 5 = 101
And
运算符会比较二进制表示形式,一次比较一个二进制位置(位)。 如果给定位置处的两个位均为 1,则在结果中将 1 置于该位置。 如果任一位为 0,则在结果中将 0 置于该位置。 在前面的示例中,结果如下:011(二进制格式的 3)
101(二进制格式的 5)
001(以二进制形式表示的结果)
结果被视为十进制值。 值 001 是 1 的二进制表示形式,因此
x
= 1。
按位 Or
运算类似,但如果两个比较位中有一个或两个均为 1,则将 1 分配至结果位。 如果两个比较位中只有一个(而不是两个)为 1,则 Xor
将 1 分配至结果位。 Not
采用单个操作数并反转所有位(包括符号位),并将该值分配至结果。 这意味着,对于有符号正数,Not
始终返回负值,而对于负数,Not
始终返回正值或零值。
AndAlso
和 OrElse
运算符不支持位运算。
注意
只能对整型类型执行位运算。 必须先将浮点值转换为整型类型,然后才能继续执行位运算。