10

私はいくつかのコードを準備しています:

for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555)
          break;
    }

    for(int c = 2001; c <= 3000; c++)    //loop c
    {
       .
       .
       .
    }
}

b ループ (ループ変数) 内int aのステートメントを使用して、メイン ループ (ループ変数) を中断したい。break;int b

どうすればいいですか?

4

11 に答える 11

34

を使用しgotoます。

for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555)
          goto loopDone;
    }

    for(int c = 2001; c <= 3000; c++)    //loop c
    {
       .
       .
       .
    }
}
loopDone:
于 2010-08-09T17:13:30.937 に答える
23

goto使用throw、使用、フラグの使用、またはリファクタリングの4つのいずれかを実行します。

多くの人がを使用gotoすることに同意しませんが、時にはそれはクリーンな解決策です。(ほとんどの場合、そうではありませんが、理由があります。)ただし、gotoワラントの使用にはリファクタリングが必要です。

2番目の解決策は、特別な例外をスローして、メインループのすぐ外側でキャッチすることです。これは例外システムの悪用であり、基本的にはさらに悪いことgotoです。gotoこれの代わりに使用してください。

3番目の解決策は、ある種のフラグを使用することです。これは基本的に「より安全」ですが、少し醜いと主張する人もいるかもしれません。(特に複数レベルの場合。そのような場合、あなたの懸念はあなたのコードがどれほど醜いかということです。)goto

私がお勧めする解決策はリファクタリングです。あなたが何をしていても、それは多すぎます。内部ループを関数に移動し、その関数を呼び出す必要があります。メインループに戻ることは、単にその関数からの復帰です。(言い換えれば、「私の仕事は終わった」)

于 2010-08-09T17:19:14.517 に答える
21

コードを関数にリファクタリングすることをお勧めします。次に、 :returnを使用する代わりに、その関数から実行できます。break

void myFunc() 
{
    for(int a = 1; a <= 100; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000; b++)    //loop b
        {
           if(b == 1555) // Logic is just an example,
              return;    // since it will always return
        }

        .
        .
        .
    }
}

これ(またはおそらくコードのより複雑なリファクタリング)は、クリーンでエレガントなソリューションに役立つはずです。または、簡単な修正が必要な場合は、条件変数を使用できます。

for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    bool cond = false;

    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555){
          cond = true;
          break;
       }
    }

    if (cond) break;

    .
    .
    .
}

他の人はを使用することを提案しgotoました。これはもう1つの簡単な修正ですが、特にコードがピアレビューされて何年も先に使用される厳しい環境で作業している場合は、これに反対することを強くお勧めします。

私の意見では、このアプローチgotoは、特に後で誰かがコードに変更を加えたときに、関数/リターンのリファクタリングよりも維持するのが少し難しいです。gotoさらに、コードに偶然出くわしたチームの他の誰かに正当化する必要があります。

于 2010-08-09T17:14:06.583 に答える
4
for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555)
          goto end;
    }

    for(int c = 2001; c <= 3000; c++)    //loop c
    {
       .
       .
       .
    }
}
end:
于 2010-08-09T17:13:44.853 に答える
4

一度に2つのそのようなループから抜け出す唯一の方法は、gotoまたはathrowまたはareturnでありthrowreturn適切でない場合があります(特にthrow、条件が例外的でない場合)。または、ある種の条件(bool breakout;)を設定し、それがtrueの場合は中断し続けることもできます。

于 2010-08-09T17:13:46.857 に答える
4

必要に応じて、内容がループである関数を作成し、returnを使用することができます。

public void bigLoop()
{
    for(int a = 1; a <= 100; a++)
    {
        for(int b = 1000; b <= 2000; b++)
        {
            if(b == 1555)
                return;
        }

        for(int c = 2001; c <= 3000; c++)
        {
            .
            .
            .
        }
    }
}//bigLoop
于 2010-08-09T17:18:38.513 に答える
4

\(◕◡◕)/

[]() {
    for(int a = 1; a <= 100; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000; b++)    //loop b
        {
           if(b == 1555)
              return;
        }

        for(int c = 2001; c <= 3000; c++)    //loop c
        {
           .
           .
           .
        }
    }
}();
于 2010-08-09T18:38:35.213 に答える
3
  1. を使用しgotoます:

    for(int a = 1; a <= 100; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000; b++)    //loop b
        {
           if(b == 1555)
              goto done;
        }
        for(int c = 2001; c <= 3000; c++)    //loop c
        {
           .
           .
           .
        }
    }
    done:
    
  2. 各ループでテストされる番兵値を設定します。

    bool sentinel = true ;
    for(int a = 1; a <= 100 && sentinel ; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000 && sentinel; b++)    //loop b
        {
           if(b == 1555)
              sentinel = false;
        }
        for(int c = 2001; c <= 3000 && sentinel; c++)    //loop c
        {
           .
           .
           .
        }
    }
    
于 2010-08-09T17:16:55.023 に答える
2

簡単な戦略の1つは、ループを別の関数に入れて、選択したポイントでリターンを実行することです。

void func()
{
    for(int a = 1; a <= 100; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000; b++)    //loop b
        {
           if(b == 1555)
              return;
        }

        for(int c = 2001; c <= 3000; c++)    //loop c
        {
           .
           .
           .
        }
    }
}

あらゆる種類の結果が、戻り値または関数の参照パラメーターとともに返される場合もあります。

于 2010-08-09T17:18:53.240 に答える
2

理想的な方法は、コードをリファクタリングして、このような複雑なネストされたループ構造が不要になるようにすることです。コードの残りの部分がどのように見えるかに応じて、bループc全体ではなくても、aループが個々の関数になる候補になる場合があります。

ループのように見え、隣接する範囲bを反復処理するので、それらを組み合わせて、ループのネストを少し減らしてみませんか?c

for (int a = 1; a <= 100; a++)    //loop a (main loop)
{
    int count = 1000;
    while (count <= 3000) // combined loops 'b' and 'c'
    {
        if (count <= 2000)
        {
            // Old loop 'b' code
            if (b == 1555)
                goto fullbreak;
        }
        else
        {
            // Old loop 'c' code
            ...
        }
        count++;
    }
}
fullbreak:

の代わりに条件変数を使用することもできますgoto。古いループから抜け出し、古いbループを処理したい場合は、古いループコード内にc設定するだけです。count = 2001b

理想的には、少なくともこれをより次のようなものにリファクタリングできるでしょう。

for (int a = 1; a <= 100; a++)    //loop a (main loop)
{
    if (process_inner_loop(pass, required, args))
        break;
}

ここで、関数はprocess_inner_loop元の2つのループをラップし、囲んでいるループから抜け出したい場合はゼロ以外を返します。これで、変数または条件変数を使用する代わりに、単純にを使用gotoできますreturn 1;

于 2010-08-09T17:39:52.523 に答える
1

この種のパターンを使用する

for(int a = 1; a <= 100; a++)
{
    int breakMain = 0;
    for(int b = 1000; b <= 2000; b++)
    {
       if(b == 1555)
       {
           breakMain = 1;
           break;
       }
    }

    if(breakMain)
         break;

    for(int c = 2001; c <= 3000; c++)
    {
       .
       .
       .
    }
}
于 2010-08-09T17:13:53.887 に答える