if ブロック内のコードが何らかの方法で実行されたのはなぜですか?
switch(v)
{
case a:
break;
...
if(condition)
{
case f:
...
break;
case g:
...
break;
}
...
case z:
...
break;
default:
}
if ブロック内のコードが何らかの方法で実行されたのはなぜですか?
switch(v)
{
case a:
break;
...
if(condition)
{
case f:
...
break;
case g:
...
break;
}
...
case z:
...
break;
default:
}
C ++コンパイラは、ルックアップテーブルを使用するか、case
ステートメントへの直接分岐を使用します。-ステートメントを無視しますif
。そのため、break
からも到達していませんcase a
。
長い答えはcase
、この方法を使用してステートメントを「オフにする」ことはできません。
代わりに、次のようなものが必要になります。
switch(v) {
case a :
break;
//...
case f :
if(condition) {
//...
}
break;
case g :
if(condition) {
//...
}
break
//...
case z :
break;
}
名前が示すように、ラベルは実際のcase
ラベルであり、ラベルと非常によく似た働きをしgoto
ます: 実行スレッドはラベルにジャンプするだけです。switch
その構造が別のネストされたステートメントでない限り、それがどの構造にあるかは問題ではありません。
これは次と同じように機能します。
if (v == f)
goto f_label;
if (condition) {
f_label:
// ...
}
実行スレッドは、truef_label:
かどうかに関係なく、ラベルにジャンプします。ラベルも同じように機能します。condition
switch
スイッチのcase句は非常に柔軟でありhacks
、それらに対していくつか行うことができます。たとえば、一部の人々がスイッチを使用してネストされたforループから抜け出すのを見てきました。上記の例でも、vがそうである場合、f
またはg
スイッチはifステートメントをスキップし、ケースのコードはスイッチの直後に実行されます。
プログラムのコンパイル時に、あるテーブルから別のswitch
テーブルにジャンプするテーブルが作成さcase
れます。これは、他の条件付き操作を無視してジャンプします。このような動作によるところで、長いブロックswitch
よりも高速です。if-else
方法に対する最良の答えは次のとおりだと思います(Nikos C.の答えに触発されました):
switch(v)
{
case a:
break;
case z:
...
break;
default:
if(condition)
{
switch(v)
{
case f:
...
break;
case g:
...
break;
default:
//former default
}
}
else
//former default
}
Switch は、その間のすべてのステートメントを無視して、一致したケースにジャンプします。意図したことを達成するには、次の 2 つの方法があります (実装する必要があるケースの数によって異なります)。
if 条件の下でより多くのケースの方法 1
if(condition) {
switch(v) {
case f :
....
break;
//...
case g :
....
break;
//...
case z :
break;
}
switch(v) {
case a :
....
break;
//...
}
if 条件の下でより少ないケースの方法 2
switch(v) {
case a :
break;
//...
case f :
if(condition) {
//...
}
break;
case g :
if(condition) {
//...
}
break
//...
case z :
break;
}