C++では、bool間で&&
(論理)と&
(ビット単位)を実行することに違いはありますか?
bool val1 = foo();
bool val2 = bar();
bool case1 = val1 & val2;
bool case2 = val1 && val2;
case1
とcase2
は同一ですか、そうでない場合、どの程度正確に異なり、なぜ一方が他方を選ぶのでしょうか。ビット単位およびブール値の移植性はありますか?
standard は、false
がゼロに変換され、true
が整数として1に変換されることを保証します。
4.7積分変換
...
宛先タイプがブールの場合は、4.12を参照してください。ソースタイプがブールの場合、値falseはゼロに変換され、値trueは1に変換されます。
したがって、指定した例の効果は同じであることが保証され、100%移植可能です。
あなたが与える場合のために、まともなコンパイラーは同一の(最適な)コードを生成する可能性があります。
ただし、ブール式expr1
およびexpr2
の場合、expr1 && expr2
は「ショートサーキット」を実行するため、expr1 & expr2
が&&
と同じであることは一般的には当てはまりません。評価。つまり、expr1
がfalse
と評価された場合、expr2
も評価されません。これは、パフォーマンス(expr2
が複雑な場合)および動作(expr2
に副作用がある場合)に影響を与える可能性があります。 (ただし、条件付き分岐を避ければ、&
フォームの方が実際には高速になることに注意してください...パフォーマンス上の理由から、この種のものをいじることはほとんど常に悪い考えです。)
したがって、指定した特定の例では、値をローカル変数にロードしてから操作する場合、動作は同じであり、パフォーマンスは非常に高くなります。
私の意見では、「短絡」動作に明確に依存しているのでない限り、意図を最も明確に表す公式を選択する必要があります。したがって、論理ANDの場合は&&
を使用し、ビット調整ANDの場合は&
を使用してください。経験豊富なC++プログラマであれば、コードを理解しやすくなります。
論理および_&&
_を使用する場合、左側の式がfalseの場合、右側の式は評価されません。
C/C++/C#コードの多くは、if (p != null && p->Foo())
のように、これに依存しています。
あなたの例では、case2(論理AND)を使用します。ビットフラグなどを扱う場合にのみビット単位を使用します。
ただし、foo()とbar()がbool(0、1)のみを返す場合、case1とcase2は同じです。
違いはありますが(2つあります)、例ではわかりません。
「&」はビット単位の「AND」演算を実行します。つまり、0x1 & 0x1 = 0x1
、 だが 0x1 & 0x2 = 0x0
。 OTOH、「&&」はブール値/論理「AND」であり、ゼロ以外の値をTRUEとして扱うため、0x1 && 0x1 = TRUE
(これは通常-1、つまりすべて1として表されます(またはC++では1として表されているかもしれませんが、忘れてしまいます))、一方で0x1 && 0x2 = TRUE
同様に。
また、 "&&"はショートサーキットであるため、最初のオペランドがFALSEの場合、2番目のオペランドは評価されません。したがって、FALSE & null_pointer->booleanField ==> null pointer exception
、FALSE && null_pointer->booleanField = FALSE
。
場合によってはビット単位の演算を使用するとパフォーマンスが若干向上する可能性がありますが、通常、ブール値を評価するときはdouble形式を使用して、ブール値のTRUEおよびFALSEの正確な表現からコードを独立させる必要があります。
アルゴリズム的には違いはありませんが、&&を使用すると、チェックを「短絡」できます。つまり、case2を決定するために、val1がfalseの場合、コンパイルされたコードはval2の値をチェックして答えを決定する理由がありません。case1では実際のANDが必要です。
現実的には、優れたコンパイラーはこれを認識して同じコードを生成します...コンパイラーがどれほど優れているかにかかっています。
"&&"は「条件付き論理AND」であり、最初の式がTRUEの場合にのみ2番目の式を評価します
"&"は "非条件論理AND"です<ブール式を使用している場合)両方の式を評価します
---([〜#〜] moreover [〜#〜] "&"は「ビット単位」の演算子で、ビットレベルで動作します。
この例は、理解を深めるのに役立ちます。
4 = 00000100 // 'four' bit set
5 = 00000101 // 'four' bit and 'one' bit set
00000100 (4) & // AND: only keep bits set in both
00000101 (5)
--------
00000100 (4)
00000100 (4) | // OR: keep bits set in either
00000101 (5)
--------
00000101 (5)
00000100 (4) ^ // EXCLUSIVE OR: keep bits only set in one but not the other
00000101 (5)
--------
00000001 (1)
論理演算子&&および|| 2つの式を評価して単一の関係結果を取得するときに使用されます。演算子&&はブール論理演算ANDに対応します。この演算は、2つのオペランドの両方がtrueの場合はtrue、それ以外の場合はfalseになります。
オペレーター||ブール論理演算ORに対応します。この演算は、2つのオペランドのいずれかがtrueの場合にtrueとなり、両方のオペランドがfalseの場合にのみfalseになります。