7

次のコードの論理演算子とビット演算子の間に機能的な違いはありますか?どちらかを使用する理由は何ですか?

typedef unsigned char BOOLEAN;

void orOperatorsComparison(BOOLEAN bBar, BOOLEAN bFoo)
{
  BOOLEAN bLogicalOr = (bFoo || bBar);
  BOOLEAN bBitwiseOr = (bFoo | bBar);

  ...  
}
4

6 に答える 6

10

「サポート」とはどういう意味ですか?

それが論理的またはあなたが意味するものである場合、それ||はブール、論理、または「または」演算子であるため、もちろん常に使用する必要があります。

短絡できるという利点がありますが、これほど単純なコードではそれほど重要ではありません。

ビット単位の場合、またはポイントがビットを操作しないときに使用されていた場合は、奇妙で奇妙な(そして修正する必要がある)と思います。

于 2013-03-21T14:59:53.050 に答える
7

他の回答はすでに短絡について話しました(しかしそれはあなたの特定のコードの問題ではありません)。しかし、ここに1つの重要な違いがあります。

何らかの理由で、入力値が[0,1]にない場合、ビット単位のORを指定すると、[0,1]にも含まれない可能性のある回答が得られます。論理ORは、0または1を与えることが保証されています。

このため、論理ORを選択する必要があります。あなたの意図は(おそらく)論理値を操作することなので、非論理演算子を使用することは非論理的です。*


*しゃれは間違いなく意図されています。

于 2013-03-21T15:02:36.377 に答える
7

ブール値|| 短絡します。最初のオペランドがtrue、の場合、2番目のオペランドは評価されません。対照的に、ビット単位の| 常に両方の引数を評価します。

于 2013-03-21T14:59:27.417 に答える
2

その特定のケースでは、いいえ、結果に違いはありません:

1 || 0 == 1
1 | 0  == 1

ここではすべての真理値表が適用されます。

どのようにして結果が得られたかについて話している場合は、違いがある可能性があります。||あなたは短絡メカニズムを持っています:

BOOLEAN bFooBar = (bFoo||bBar) // if bFoo is TRUE, we never look at bBar
                               // vs
BOOLEAN bFooBar = (bFoo|bBar)  // where we take into account both values

つまり、長短は、論理演算子とビット演算子を誤って使用して同じ結果を得ることができるということですが、なぜそうするのでしょう。それが間違っていることを知っていて、それが悪い、見つけるのが難しいバグにつながる可能性があることを知っている場合は、言語が意図した仕事のためにあなたに与えたツールを使用してください。

于 2013-03-21T15:08:21.790 に答える
1

ビット単位または演算子は、論理演算子が短絡している間は短絡しません。つまりbFoo、trueの場合、bBar評価されることはありません。

于 2013-03-21T15:00:18.560 に答える
1

次の場合、論理演算子とビット演算子の間に機能的な違いはありますか?

はい、あります(他の人が指摘しているように遅延評価)。

どちらかをサポートする理由はありますか?

どういうわけかそれらが同等である場合、論理演算子を使用する場合は、型によって意図されたセマンティクスを保持することです。参照:驚き最小の原則

于 2013-03-21T15:08:53.260 に答える