[解決済み] スイッチの内部でループから抜け出すには?
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
. 例外なし。変更しやすい。読みやすい。修正しやすい。さらにコードも。
- ループの作業負荷の知識をループ自体から分離します。
- コードを管理している人が簡単に機能を拡張できるようにします。
- 複数の終了条件を一度に割り当てることができます。
- 実行するコードから終了節を分離します。
- 原子力発電所にとってより安全です。)
2つ目のポイントは重要です。コードがどのように動作するかは知りませんが、もし誰かがメインループが他のスレッド (またはプロセス) にいくらかの CPU 時間を持たせるように私に尋ねた場合、2 つのソリューションが思い浮かびます。
オプション #1
簡単にポーズを挿入する。
while( isValidState() ) {
execute();
sleep();
}
オプション#2
実行をオーバーライドする。
void execute() {
super->execute();
sleep();
}
を埋め込んだループよりもシンプル(つまり読みやすい)です。
switch
. このコードでは
isValidState
メソッドはループを継続するかどうかだけを決定する必要があります。このメソッドの主要な部分は
execute
メソッドに抽象化されるべきです。これにより、サブクラスはデフォルトの動作をオーバーライドすることができます (埋め込まれた
switch
と
goto
).
Pythonの例
StackOverflowに投稿された次の回答(Pythonの質問)を対比してみましょう。
- 永遠にループします。
- ユーザーに選択肢を入力させる。
- ユーザーの入力が「restart」であれば、永遠にループを続ける。
- そうでなければ、永久にループを停止する。
- 終了します。
while True:
choice = raw_input('What do you want? ')
if choice == 'restart':
continue
else:
break
print 'Break!'
バーサス
- ユーザーが選択したものを初期化します。
- ユーザーの選択肢が「restart」である間、ループする。
- ユーザーに選択肢を入力するよう求める。
- 終了します。
choice = 'restart';
while choice == 'restart':
choice = raw_input('What do you want? ')
print 'Break!'
ここで
while True
は、誤解を招くような複雑すぎるコードになります。
関連
-
[解決済み] jQueryの各ループから抜け出すには?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] Rubyのswitch文の書き方
-
[解決済み] YAML の文字列を複数行に渡って分割するには?
-
[解決済み] Javaでネストされたループから抜け出すには?
-
[解決済み] オブジェクトをメンバーとして、プレーンなJavaScriptオブジェクトをループさせる方法
-
[解決済み] Pythonで改行(行継続)をするにはどうしたらいいですか?
-
[解決済み] C#のループ - breakとcontinue
-
[解決済み】PHPの'foreach'は実際どのように動作するのですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み】ループや関数をサポートする言語で「goto」の正当な使用例はあるのか?