web-dev-qa-db-ja.com

&&と&の間にブール値の違いはありますか?

C++では、bool間で&&(論理)と&(ビット単位)を実行することに違いはありますか?

bool val1 = foo();
bool val2 = bar();

bool case1 = val1 & val2;
bool case2 = val1 && val2;

case1case2は同一ですか、そうでない場合、どの程度正確に異なり、なぜ一方が他方を選ぶのでしょうか。ビット単位およびブール値の移植性はありますか?

30
WilliamKF

standard は、falseがゼロに変換され、trueが整数として1に変換されることを保証します。

4.7積分変換

...

宛先タイプがブールの場合は、4.12を参照してください。ソースタイプがブールの場合、値falseはゼロに変換され、値trueは1に変換されます。

したがって、指定した例の効果は同じであることが保証され、100%移植可能です。

あなたが与える場合のために、まともなコンパイラーは同一の(最適な)コードを生成する可能性があります。

ただし、ブール式expr1およびexpr2の場合、expr1 && expr2は「ショートサーキット」を実行するため、expr1 & expr2&&と同じであることは一般的には当てはまりません。評価。つまり、expr1falseと評価された場合、expr2も評価されません。これは、パフォーマンス(expr2が複雑な場合)および動作(expr2に副作用がある場合)に影響を与える可能性があります。 (ただし、条件付き分岐を避ければ、&フォームの方が実際には高速になることに注意してください...パフォーマンス上の理由から、この種のものをいじることはほとんど常に悪い考えです。)

したがって、指定した特定の例では、値をローカル変数にロードしてから操作する場合、動作は同じであり、パフォーマンスは非常に高くなります。

私の意見では、「短絡」動作に明確に依存しているのでない限り、意図を最も明確に表す公式を選択する必要があります。したがって、論理ANDの場合は&&を使用し、ビット調整ANDの場合は&を使用してください。経験豊富なC++プログラマであれば、コードを理解しやすくなります。

37
Nemo

論理および_&&_を使用する場合、左側の式がfalseの場合、右側の式は評価されません。

C/C++/C#コードの多くは、if (p != null && p->Foo())のように、これに依存しています。

あなたの例では、case2(論理AND)を使用します。ビットフラグなどを扱う場合にのみビット単位を使用します。

ただし、foo()とbar()がbool(0、1)のみを返す場合、case1とcase2は同じです。

13

違いはありますが(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 exceptionFALSE && null_pointer->booleanField = FALSE

場合によってはビット単位の演算を使用するとパフォーマンスが若干向上する可能性がありますが、通常、ブール値を評価するときはdouble形式を使用して、ブール値のTRUEおよびFALSEの正確な表現からコードを独立させる必要があります。

8
Hot Licks

アルゴリズム的には違いはありませんが、&&を使用すると、チェックを「短絡」できます。つまり、case2を決定するために、val1がfalseの場合、コンパイルされたコードはval2の値をチェックして答えを決定する理由がありません。case1では実際のANDが必要です。

現実的には、優れたコンパイラーはこれを認識して同じコードを生成します...コンパイラーがどれほど優れているかにかかっています。

4
mah

"&&"は「条件付き論理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)
3
makiSTB

論理演算子&&および|| 2つの式を評価して単一の関係結果を取得するときに使用されます。演算子&&はブール論理演算ANDに対応します。この演算は、2つのオペランドの両方がtrueの場合はtrue、それ以外の場合はfalseになります。

オペレーター||ブール論理演算ORに対応します。この演算は、2つのオペランドのいずれかがtrueの場合にtrueとなり、両方のオペランドがfalseの場合にのみfalseになります。

0
Javeria