1. ホーム
  2. c++

[解決済み] スイッチの内部でループから抜け出すには?

2022-06-04 07:40:32

質問

次のようなコードを書いています。

while(true) {
    switch(msg->state) {
    case MSGTYPE: // ... 
        break;
    // ... more stuff ...
    case DONE:
        break; // **HERE, I want to break out of the loop itself**
    }
}

何か直接的な方法はないでしょうか?

私はフラグを使用し、スイッチの直後に条件付きブレークを置くことによって、ループから抜け出すことができることを知っています。ただ、C++がすでにこのためのいくつかの構成を持っているかどうかを知りたいのです。

どのように解決するのですか?

前提

以下のコードは、言語や希望する機能に関係なく、悪い形式とみなされるべきです。

while( true ) {
}

支持論証

その while( true ) ループは、それが原因で貧しいフォームです。

  • while ループの暗黙の了解を破ります。
    • whileループの宣言では、明示的に のみ という終了条件を明示しなければなりません。
  • 永遠にループすることを暗示しています。
    • ループ内のコードは、終了句を理解するために読む必要があります。
    • 永遠に繰り返されるループは、ユーザーがプログラム内からプログラムを終了させることを妨げます。
  • 非効率的です。
    • ループの終了条件が複数あり、"true"のチェックも含まれます。
  • バグが発生しやすい。
    • 反復ごとに必ず実行されるコードをどこに置くか、容易に決定できない。
  • 不必要に複雑なコードにつながる。
  • ソースコードの自動解析。
    • バグの発見、プログラムの複雑性の分析、セキュリティ チェック、またはその他のソース コードの動作をコード実行なしで自動的に導き出すために、最初のブレーク条件を指定すると、アルゴリズムが有用な不変量を決定できるようになり、それによって自動ソース コード解析メトリクスを向上させることができます。
  • 無限のループ。
    • もし誰もが常に while(true) を使うようになると、ループが実際に終了条件を持たない場合に、簡潔に伝える能力を失ってしまいます。(議論の余地なく、これはすでに起こっているので、ポイントは無意味です)。

Go"に代わるものです。

以下のコードがより良いフォームです。

while( isValidState() ) {
  execute();
}

bool isValidState() {
  return msg->state != DONE;
}

メリット

フラグがない なし goto . 例外なし。変更しやすい。読みやすい。修正しやすい。さらにコードも。

  1. ループの作業負荷の知識をループ自体から分離します。
  2. コードを管理している人が簡単に機能を拡張できるようにします。
  3. 複数の終了条件を一度に割り当てることができます。
  4. 実行するコードから終了節を分離します。
  5. 原子力発電所にとってより安全です。)

2つ目のポイントは重要です。コードがどのように動作するかは知りませんが、もし誰かがメインループが他のスレッド (またはプロセス) にいくらかの CPU 時間を持たせるように私に尋ねた場合、2 つのソリューションが思い浮かびます。

オプション #1

簡単にポーズを挿入する。

while( isValidState() ) {
  execute();
  sleep();
}

オプション#2

実行をオーバーライドする。

void execute() {
  super->execute();
  sleep();
}

を埋め込んだループよりもシンプル(つまり読みやすい)です。 switch . このコードでは isValidState メソッドはループを継続するかどうかだけを決定する必要があります。このメソッドの主要な部分は execute メソッドに抽象化されるべきです。これにより、サブクラスはデフォルトの動作をオーバーライドすることができます (埋め込まれた switchgoto ).

Pythonの例

StackOverflowに投稿された次の回答(Pythonの質問)を対比してみましょう。

  1. 永遠にループします。
  2. ユーザーに選択肢を入力させる。
  3. ユーザーの入力が「restart」であれば、永遠にループを続ける。
  4. そうでなければ、永久にループを停止する。
  5. 終了します。
コード
while True: 
    choice = raw_input('What do you want? ')

    if choice == 'restart':
        continue
    else:
        break

print 'Break!' 

バーサス

  1. ユーザーが選択したものを初期化します。
  2. ユーザーの選択肢が「restart」である間、ループする。
  3. ユーザーに選択肢を入力するよう求める。
  4. 終了します。
コード
choice = 'restart';

while choice == 'restart': 
    choice = raw_input('What do you want? ')

print 'Break!'

ここで while True は、誤解を招くような複雑すぎるコードになります。