e1
とを 2 つのブールe2
式にします。次に、Cのとe1 && e2
同等ですか?e2 && e1
私の直感はイエスだと言っています。単純な論理A & B
では と同等B & A
です。これはCでも同じですか?
e1
とを 2 つのブールe2
式にします。次に、Cのとe1 && e2
同等ですか?e2 && e1
私の直感はイエスだと言っています。単純な論理A & B
では と同等B & A
です。これはCでも同じですか?
論理的には、そうです。 論理的な観点からe1 && e2
異なる結果になることは決してありません。e2 && e1
しかし、コードの観点からは、e1
またはの評価にe2
副作用がある場合、no、それらは完全に同等ではありません。
具体的には、 のチェーンで関数&&
を使用することがあります。
if( isHungry() && hasFood() ) eat() ;
通常は、最初に最も安い条件を評価条件に入れ、最初の条件が真である場合にのみ 2 番目の条件をチェックします。 短絡評価は、これが起こることを保証するものです。AND 論理演算の最初の条件が falseの場合、最終結果が TRUE にならないため、2 番目のステートメントは評価されません。(FALSE && (TRUE && TRUE && TRUE && TRUE)) == FALSE)
言い換えれば、お腹が空いていなければ、わざわざ冷蔵庫をチェックすることはないでしょう。
場合によっては、短絡評価が行われるという事実に依存し、それに依存するコードを書くことがあります。このタイプのことは、以下のコメントに示されています。
if( x && x->eval() ) { /* do something */ }
だから、x=NULL
上で言ってください。何が起こるか?NULL ポインターを参照しようとしていますか? と書くべきか
if( x )
{
if( x->eval() )
{
// do something
}
}
私はまったくノーと言った!短絡評価は、 の場合、演算子x==0
の右側のオペランドが で調べられないことを意味します。 評価されず、null ポインター例外は発生しません。&&
if( x && x->eval() )
x->eval()
もう 1 つ気を付けなければならないことは、if ステートメントで実行する関数に、何らかのカウンターをインクリメントするなどの副作用があるかどうかです。したがって、hasFood()にfridgeCount++
.
短い cct 評価のイベントでは、関数は実行されないため、if ステートメントを実行したときに発生すると予想される副作用は発生しない可能性があります。
OR 演算子にも短絡評価があり、 でのみ、 TRUE になるif( e1 || e2 )
場合、ステートメントは TRUE に短絡さe1
れます (その場合、e2 は評価さえされず、式全体が と見なされますTRUE
)。
この動作は、C/C++、Java、JavaScript、PHP、Python、およびその他の多くの言語に当てはまります。
e1 && e2
短絡評価e2 && e1
のためと同等ではない可能性があるため、これらの式に副作用がある場合、異なる動作が発生する可能性があります。セクション論理AND演算子のパラグラフ4のC99ドラフト標準は次のように述べています。6.5.13
ビットごとのバイナリ & 演算子とは異なり、&& 演算子は左から右への評価を保証します。最初のオペランドの評価の後にシーケンス ポイントがあります。最初のオペランドが 0 と等しい場合、2 番目のオペランドは評価されません。
したがって、最初のオペランドが と等しい場合、2 番目のオペランドは評価されません0
。したがって、それが評価e1
されるがゼロ以外の値に評価されるとしましょう。この場合は次のようになります。0
e2
e1 && e2
次にe1
評価されますが評価されe2
ませんが、この場合:
e2 && e1
両方ともe1
評価e2
されます。