6

まず、始める前に、私は VC++ 2008 プロフェッショナルを使用しており、Windows OS で Intel Core2 を実行しています。また、このコードは、Windows を実行している core2/corei7 以外では決して実行されないことも知っています。

次のような 2 つの条件を持つ while ループがあります: 注: これはかなり簡略化されたバージョンです。

while((a != b) && (array[a] < c))

最初の条件(a != b)が false を生成した場合、2 番目の条件も評価されますか? それとも、ループはすぐに終了しますか?

私はいくつかのテストを行いましたが、それは確かに本当のようです.

ただし、ここに問題があります。最初の条件が false と評価された場合、2 番目の条件が評価されると、アクセス違反が生成されます。ただし、私が見ることができることから、最初の条件が false として評価されると、プログラムは 2 番目の条件を評価することを気にせず、ループを終了するので、私は救われます。

問題は、アクセス違反の問題を完全に取り除くには、非常に優れたきちんとしたコードを突然爆発させないことです。ただし、小さな「バグ」 (バグではなく、コンパイラの最適化であることはわかっています) のために、私はそれを回避できるようです。また、これはおそらく良いプログラミング手法ではないこともわかっていますが、正直なところ、私の状況では、それが機能する場合、私はすでにゲームの先を行っています。

私の質問は、この「バグ」またはプログラミングの不正行為が戻ってきて、いつか私を噛むのでしょうか? このセクションを徹底的にテストしたことを考慮しても、これを使用するのはこの 1 回だけですか?

4

6 に答える 6

23

最初の条件が true に評価されない限り、2 番目の条件は評価されません。あなたはこれを頼りにすることができます。何百万行ものコードが機能するのは、これが C および C++ が短い論理式の評価を行う方法だからです。

あなたはそれを使用して信頼することができます。最初の式が false と評価された場合、2 番目の式は評価を開始しません。

于 2009-07-10T07:09:30.573 に答える
4

これはバグではありません。C++ は短絡評価を使用するため、最初の条件が false の場合、2 番目の条件は評価されません。

于 2009-07-10T07:10:44.173 に答える
2

評価されません。しかし、自分が書いたルーチンが戻ってきて噛み付くのではないかとまったく心配している場合は、自分が書いているものを再評価する必要があります。あなたはそれが貧弱なプログラミングの実践であることを認めました。あなたはすでにそれが問題になることを知っています。これらの条件が満たされたら、問題を修正するだけです。朝になると、自分を嫌いになることが少なくなります。

于 2009-07-10T07:10:21.930 に答える
1

最初の条件が真でない場合、2 番目の条件は評価されません。あなたが言ったように、この最適化はすべての C++ コンパイラーによって行われます。

それでもうまくいかない場合は、while に単純な if ステートメントを追加します。

while ( a != b ) {
    if ( array[a] < c )
    {
         // your code goes here.
    }
    else
    {
        break;
    }
}
于 2009-07-10T09:12:58.437 に答える
1

言語はこの短絡動作を保証しているため、使用してもまったく心配する必要はありません。|| でも動作します。- 最初の条件が真の場合、2 番目の条件は評価されません。

于 2009-07-10T07:23:19.373 に答える
1

C++ の論理 AND および OR 演算子の短絡動作に依存することは、悪い習慣と見なされるべきではありません。これは完全に慣用的であり、多くの場合、より明確で簡潔なコードにつながります。

例えば

std::auto_ptr< SomeObject > data;

短絡あり&&

// Clear expired data, if present
if( data.get() && data->expired )
    data.reset();

の短絡を使用しないと、より冗長なコードにつながる&&余分なレベルが必要になります。if

// Clear expired data, if present
if( data.get() )
{
    if ( data->expired )
        data.reset();
}
于 2009-07-10T07:25:04.100 に答える