Visual Basic 中的逻辑运算符和位运算符
逻辑运算符比较 Boolean 表达式,并返回 Boolean 结果。 And、Or、AndAlso、OrElse 和 Xor 运算符是二元运算符,原因是它们接受两个操作数,而 Not 运算符是一元运算符,原因是它只接受一个操作数。 上述的某些运算符也可对整数值执行按位逻辑运算。
一元逻辑运算符
Not 运算符 (Visual Basic) 对 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 运算符 (Visual Basic) 对两个 Boolean 表达式执行逻辑合取。 如果两个表达式的计算结果均为 True,则 And 返回 True。 如果其中至少一个表达式的计算结果为 False,则 And 返回 False。
Or 运算符 (Visual Basic) 对两个 Boolean 表达式执行逻辑析取或包含。 如果任意一个表达式的计算结果为 True,或两个表达式的计算结果均为 True,则 Or 返回 True。 如果两个表达式的计算结果都不是 True,则 Or 返回 False。
异或运算符 (Visual Basic) 对两个 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 运算符 (Visual Basic) 与 And 运算符非常类似,因为它也对两个 Boolean 表达式执行逻辑合取。 两者之间的主要差异是 AndAlso 表现出短路行为。 如果 AndAlso 表达式中第一个表达式的计算结果为 False,则不会计算第二个表达式的值,因为它不会改变最终结果,AndAlso 将返回 False。
同样,OrElse 运算符 (Visual Basic) 对两个 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() 内部的某些重要代码将不会运行。 即使 12 > 45 返回 False,第一个 If 语句也会调用 checkIfValid(),因为 And 不会短路。 第二个 If 语句不会调用 checkIfValid(),因为当 12 > 45 返回 False 时,AndAlso 将会使第二个表达式短路。 即使 12 < 45 返回 True,第三个 If 语句也会调用 checkIfValid(),因为 Or 不会短路。 第四个 If 语句不会调用 checkIfValid(),因为当 12 < 45 返回 True 时,OrElse 将会使第二个表达式短路。
按位运算
按位运算采用二进制(以 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。
除了在任何一个比较位是 1 或两个比较位都是 1 的情况下将 1 赋予结果位以外,按位 Or 运算与此类似。 Xor 在比较的位正好只有一个是 1(而不是两者都是 1)时将 1 赋给结果位。 Not 采用单个操作数并反转所有位(包括符号位),然后将该值赋予结果。 这意味着,对于有符号正数,Not 始终返回负值,而对于负数,Not 始终返回正值或零。
AndAlso 和 OrElse 运算符不支持按位运算。
备注
只能对整型执行按位运算。浮点值必须转换为整型后,才能执行按位运算。