Visual Basic 中的逻辑运算符和位运算符

逻辑运算符会比较 Boolean 表达式并返回 Boolean 结果。 AndOrAndAlsoOrElseXor 运算符是二元的,因为它们采用两个操作数,而 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

下面的示例演示 AndOrXor 运算符。

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 中的代码。

下面的示例演示了 AndOr 和其短路对应项之间的差异。

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 始终返回正值或零值。

AndAlsoOrElse 运算符不支持位运算。

注意

只能对整型类型执行位运算。 必须先将浮点值转换为整型类型,然后才能继续执行位运算。

请参阅