1

重複の可能性:
コーディング標準/C++でのコーディングのベストプラクティス

私はDo-Whileループをあまり使用していませんが、複数の出口点に関係することのリストを調べたいが、通過するだけの特定のカテゴリのケースで、Do-Whileループを使用してロジックを実行していることに気付きました。一度だけ。私は常に条件に「while(TRUE)」と「if(TRUE)break」を持っています。ループの最後で、一度だけ通過したいので。[あるいは、これら2つを「while(FALSE)」として組み合わせることができると思います。]

Do {

  // do some stuff

  if (!CheckCondition1) break;
  // do some stuff

  if (!CheckCondition2) break;
  // do some stuff

  ...

  // or delete this and change to while (FALSE);
  if (TRUE) break;
} while (TRUE);

私はこれらの場合にのみDo-While構造を使用してきましたが、それが「許容できる」使用方法なのか、それともより良い方法があるのか​​わかりませんでした。ありがとう。

4

7 に答える 7

5

私が知っている他の唯一のアプローチは、コードを関数に入れて、のreturn代わりに使用することですbreak
ただし、これには独自の欠点があります。ローカル変数にアクセスできない、存在してはならない関数を作成する際の追加の複雑さ、および一部のコーディング標準では、「単一の出口点」の使用を強制される可能性があります。

だから、do {...} while(false);マスクされたに他ならない、はるかに良く見えますgoto。また、スパゲッティコードを回避するためにが禁止されたことを忘れないでください。また、goto標準のC制御フロー構造でフローを記述できることが証明されました。さて、あなたはちょうどそれをしました。

于 2011-04-22T02:25:58.703 に答える
5

C(および例外を回避している場合はC ++)では、これにaを使用することをお勧めしますgoto。さて、すべての構造化whileループをgotoに置き換えないでください。ただし、さまざまなエラー状態をチェックし、障害からクリーンアップするというこのパターンがある場合は、goto間違いなく保証されます。これは、表現するための最も明確な方法の1つです。あなたが達成しようとしていること。

(正規のリストは、CまたはC ++の優れたgotoの例にあります

  // do some stuff

  if (!CheckCondition1) goto failure;
  // do some stuff

  if (!CheckCondition2) goto failure;
  // do some stuff

  return success_code;
failure:

  //do something to clean up after a failure.
  //(I added that part, so it would be clear why you couldn't just return early)

  return failure_code;

クリーンアップする必要があるものに応じて、このパターンにはいくつかのバリエーションがあります。

  1. 関数のどこまで進んだとしても、クリーンアップが同じである場合。
  2. 割り当てられた順序とは逆の順序でクリーンアップする必要があり、失敗した場所によって量が異なります。

そして、あなたがそれをきれいにしなければならないとき:

  1. 障害が発生した場合にのみクリーンアップする必要がある場合。
  2. 成功した場合に同じものをクリーンアップする必要がある場合。

そして、関数から返されるものは次のとおりです。

  1. 障害が発生した場合でも、常に計算値を返します。
  2. 成功した場合は計算値を返し、失敗した場合は特別な番兵を返します。

これらのバリエーションのいくつかは2つの同等に有効な方法で設計できるため、これらのさまざまなバリエーションのそれぞれがどのように見えるかを明示的に指定するコーディング標準を作成する必要があります。

注:これは、を許可する言語でのみ機能しますgoto。それはJava、そして多分C#を除外します。

于 2011-04-22T02:43:07.920 に答える
2

これを行う場合は、while (true) {...}の代わりにを使用することをお勧めしますdo {...} while (true)。この2つは機能的には同等ですが、最初の形式の方が読みやすくなっています。

ほとんどの人と同じように、私はコードを上から下に読みます。while (true)ループの開始時に見ると、ループ終了ロジックがループ本体内にある必要があることがすぐにわかります。しかし、私が見た場合、これを理解do {..するために対応するものを検索する必要があります。...} while (

(これは、ループ内のさまざまなポイントでフラグが設定されている場所while (true)よりも、ブレークがあるかどうかの問題と直交しています。)while (flag)

于 2011-04-22T04:47:44.377 に答える
0

私はこの使用法をdo...while非常に混乱させて醜いものだと思います。少なくともCでは、for (;;)は無限ループの標準的なイディオムです。まったく見ると、その状態が重要になり、そこに(これも悪いスタイルです)見つけるだけdoの、非日常的な何かを期待するようになります...whileTRUE

于 2011-04-22T02:24:19.843 に答える
0

{...} while(false);を実行します。これは通常、cのエラーの処理に使用されます。次に例を示します。

int some_func(void)
{
    do {
        /* alloc some heap resources */

        /* do something */

        if (something goes wrong) break; /* error handling */

        /* do other things */

        return SUCCESS; 
    } while (false);

    /* release resources */

    return FAILURE;
}

C ++では、try { ... } catch(...)代わりに使用することをお勧めします。

于 2011-04-22T02:38:08.557 に答える
0

上記の場合、なぜあなたもやりたいのですか?何をしているかにもよりますが、以下のようなことをしてください。

 if (!CheckCondition1) return;
 // do some stuff

 if (!CheckCondition2) return;
 // do some stuff
于 2011-04-22T02:17:16.320 に答える
-1

私はこれの使用法がdo { } while();非常に受け入れられることを発見しました。あなたが置くべきであるという条件でwhile(0)(そして今あなたはcontinueまた使うことができます)。万が一、そうしないbreak;とループが終了してしまうからです。興味深いことに、私は前の会社の製品コードでそのような使用法を見て、専門家によってレビューされました。

を使用することを考えるかもしれませんreturn。しかし、そのアプローチの問題はデストラクタです。以下のシナリオを検討してください。

void fun ()
{
  CLASS_a a1, a2, a3, a4;
  CLASS_b b1, b2, b3, b4;

  ...
  return 1;
  ...
  return 2;
  ...
  return 3;
  ...
  return 4;
}

すべてのreturnステートメントで、上記のすべてのオブジェクトのデストラクタコードが配置されます。これにより、無意識のうちにコードサイズが大きくなる場合があります。さらに、出口点を少なくする方が良いと思います。これにより、コードのデバッグが容易になります。

編集:ステートメント内にいるときにループを終了することはできないため、よりcontinueもむしろ置くことをお勧めします。breakbreakswitch()

于 2011-04-22T02:28:51.697 に答える