Visual Basic の論理演算子とビット処理演算子

論理演算子を使用すると、Boolean 式を比較し、Boolean の結果を返すことができます。 AndOrAndAlsoOrElse、および Xor の各演算子は、2 つのオペランドを受け取るため、"二項" です。Not 演算子は、1 つのオペランドを受け取るため、"単項" です。 これらの演算子の一部を使用して、整数値に対してビットごとの論理演算を実行することもできます。

単項論理演算子

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 演算子を使用すると、2 つの Boolean 式に対して "論理積" を実行できます。 両方の式が True に評価される場合、And からは True が返されます。 式の少なくとも 1 つが False に評価される場合、And からは False が返されます。

Or 演算子を使用すると、2 つの Boolean 式に対して "論理和" または "論理包含" を実行できます。 いずれかの式が True に評価されるか、または両方が True に評価される場合、Or からは True が返されます。 どちらの式も True に評価されない場合、Or からは False が返されます。

Xor 演算子を使用すると、2 つの Boolean 式に対して "排他的論理和" を実行できます。 両方ではなく 1 つの式のみが True に評価される場合、Xor からは True が返されます。 両方の式が True に評価されるか、両方が False に評価される場合、Xor からは False が返されます。

次の例は、AndOr、および 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 演算子を使用すると、2 つの Boolean 式に対して論理積も実行されるという点で、And 演算子とよく似ています。 この 2 つの主な違いは、AndAlso が "短絡" 動作を示すことです。 AndAlso 式の 1 つ目の式が False に評価される場合、最終結果を変更できないため、2 つ目の式は評価されず、AndAlso からは False が返されます。

同様に、OrElse 演算子を使用すると、2 つの Boolean 式に対して短絡論理和を実行できます。 OrElse 式の 1 つ目の式が True に評価される場合、最終結果を変更できないため、2 つ目の式は評価されず、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() 内の一部の重要なコードが実行されないことに注意してください。 12 > 45 から False が返される場合でも、1 つ目の If ステートメントでは checkIfValid() が呼び出されます。これは、And では短絡が実行されないためです。 2 つ目の If ステートメントでは checkIfValid() が呼び出されません。これは、12 > 45 から False が返されると、AndAlso によって 2 つ目の式が短絡されるためです。 12 < 45 から True が返される場合でも、3 つ目の If ステートメントでは checkIfValid() が呼び出されます。これは、Or では短絡が実行されないためです。 4 つ目の If ステートメントでは checkIfValid() が呼び出されません。これは、12 < 45 から True が返されると、OrElse によって 2 つ目の式が短絡されるためです。

ビットごとの演算

ビットごとの演算では、2 つの整数値がバイナリ (base 2) 形式で評価されます。 対応する位置にあるビットが比較され、比較に基づいて値が割り当てられます。 And 演算子の例を次に示します。

Dim x As Integer
x = 3 And 5

前の例では、x の値を 1 に設定しています。 これは次の理由によるものです。

  • 値はバイナリとして扱われます。

    バイナリ形式の 3 = 011

    バイナリ形式の 5 = 101

  • And 演算子を使用すると、バイナリ表現を一度に 1 つのバイナリ位置 (ビット) ずつ比較できます。 特定の位置の両方のビットが 1 の場合、結果のその位置に 1 が配置されます。 いずれかのビットが 0 の場合、結果のその位置に 0 が配置されます。 前の例では、これは次のように機能します。

    011 (バイナリ形式の 3)

    101 (バイナリ形式の 5)

    001 (バイナリ形式の結果)

  • 結果は 10 進として扱われます。 値 001 は 1 のバイナリ表現であるため、x = 1 です。

ビットごとの Or 演算は似ていますが、比較されるビットのいずれか、または両方が 1 の場合、結果ビットに 1 が割り当てられる点が異なります。 Xor を使用すると、比較されたビットの (両方ではなく) いずれかが 1 の場合、結果ビットに 1 が割り当てられます。 Not を使用すると、1 つのオペランドを受け取り、符号ビットを含むすべてのビットが反転され、その値が結果に割り当てられます。 つまり、符号付き正数の場合、Not からは常に負の値が返され、負数の場合、Not からは常に正または 0 の値が返されます。

AndAlso 演算子と OrElse 演算子はビットごとの演算をサポートしていません。

Note

ビットごとの演算は、整数型に対してのみ実行できます。 ビットごとの演算を進める前に、浮動小数点値を整数型に変換する必要があります。

関連項目