web-dev-qa-db-ja.com

C#の論理ANDと条件AND、ORの違いは何ですか?

可能性のある複製:
と||または演算子の違いは何ですか?

論理ANDおよびOR:

(x & y)
(x | y)

条件付きANDおよびOR:

(x && y)
(x || y)

私はこれまで条件付きオペランドについてのみ知っていました。私はそれが何をするのか、if文でそれをどのように適用するのかを知っています。しかし、論理オペランドの目的は何ですか?

47
Sahat Yalkabov

「論理的」という一般的な概念は両方の場合に当てはまるため、「論理的対条件的」ではなく「ビット単位対条件的」と考えることを好みます。

_x & y    // bitwise AND, 0101 & 0011 = 0001
x | y    // bitwise OR,  0101 | 0011 = 0111

x && y   // true if both x and y are true
x || y   // true if either x or y are true
_

編集

一般的な需要により、引数の評価が異なることにも言及する必要があります。条件付きバージョンでは、操作全体の結果が最初の引数で決定できる場合、2番目の引数は評価されません。これは、短絡評価と呼ばれます。ビット演算では、最終値を計算するために両側を評価する必要があります。

例えば:

_x.foo() && y.bar()
_

これは、y.bar()trueに評価される場合にのみx.foo()を呼び出します。逆に、

_x.foo() || y.bar()
_

y.bar()falseと評価される場合にのみ、x.foo()を呼び出します。

77
Cogwheel
(x && y) 

怠け者です。 xがtrueの場合にのみyを評価します。

(x & y)

怠zyではありません。 yは常に評価されます。

33
Robert Harvey

更新された回答-私のオリジナルは誤解を招き、不完全でした。

まず、この質問に対する私のコメントと回答の多くについて謝罪する必要があります。

仕様を読んだ後、ビット演算子と条件演算子の区別はあまり明確ではありません。

セクションによると ECMA-334の14.1

&、^、および|演算子は論理演算子と呼ばれます。

整数演算の場合:

1&演算子は、2つのオペランドのビットごとの論理ANDを計算します。演算子は、2つのオペランドのビットごとの論理ORを計算し、^演算子は、2つのオペランドのビットごとの論理排他ORを計算します。これらの操作。

セクションによると 14.11:

&&および||演算子は条件付き論理演算子と呼ばれます。 2これらは、「短絡」論理演算子とも呼ばれます。

14.11.1

1 &&または||のオペランドがbool型であるか、オペランドが適用可能な演算子&またはoperator |を定義しないがboolへの暗黙的な変換を定義する型である場合、演算は次のように処理されます。2演算x && yはxとして評価されますか? y:偽。 3言い換えると、xは最初に評価され、bool型に変換されます。 4次に、xがtrueの場合、yが評価されてbool型に変換され、これが演算の結果になります。 5それ以外の場合、操作の結果は偽です。 6操作x || yはxとして評価されますか? true:y。 7つまり、xは最初に評価され、bool型に変換されます。 8次に、xがtrueの場合、演算の結果はtrueです。 9それ以外の場合、yは評価されてbool型に変換され、これが操作の結果になります。

14.11.2

1 &&または||のオペランドが適用可能なユーザー定義演算子&またはoperator |を宣言する型で、次の両方が真でなければなりません。ここで、Tは選択された演算子が宣言されている型です。2戻り値の型と選択された各パラメーターの型3つまり、演算子は、T型の2つのオペランドの論理ANDまたは論理ORを計算し、T型の結果を返す必要があります。演算子trueおよび演算子falseの宣言2項1これらの要件のいずれかが満たされない場合、コンパイル時エラーが発生する2それ以外の場合、&&または||演算は、ユーザー定義の演算子trueまたは演算子falseと選択されたユーザー定義演算子:3操作x && yは、T.false(x)?x:T。&(x、y)として評価されます。ここで、T.false(x)は、Tで宣言された演算子falseの呼び出しです。 、T。&(x、y)は選択された演算子&の呼び出しです。4つまり、xが最初に評価され、演算子falseがreで呼び出されます。 xが間違いなくfalseであるかどうかを判断する結果。 5次に、xが完全にfalseの場合、演算の結果はxに対して以前に計算された値になります。 6それ以外の場合、yが評価され、選択された演算子&は、xに対して以前に計算された値とyに対して計算された値に対して呼び出され、演算の結果が生成されます。 7操作x || yはT.true(x)として評価されますか? x:T. |(x、y)。ここで、T.true(x)はTで宣言された演算子trueの呼び出しであり、T。|(x、y)は選択された演算子|の呼び出しです。 8つまり、xが最初に評価され、結果に対して演算子trueが呼び出されて、xが確実に真であるかどうかが判断されます。 9次に、xが確実に真である場合、演算の結果はxに対して以前に計算された値です。 10それ以外の場合、yが評価され、選択された演算子| xに対して以前に計算された値とyに対して計算された値に対して呼び出され、操作の結果が生成されます。 Paragraph 3 1これらの操作のいずれにおいても、xで与えられる式は一度だけ評価され、yで与えられる式は評価されないか、一度だけ評価されます。パラグラフ4 1演算子trueと演算子falseを実装する型の例については、§18.4.2を参照してください。

11
John Weldon