Использование продолжения в инструкции switch
Я хочу перейти из середины инструкции switch
в оператор цикла в следующем коде:
while (something = get_something())
{
switch (something)
{
case A:
case B:
break;
default:
// get another something and try again
continue;
}
// do something for a handled something
do_something();
}
Является ли это допустимым способом использования continue
? Операторы continue
игнорируются операторами switch
? Здесь C и С++ отличаются от их поведения?
Ответы
Ответ 1
Хорошо, оператор continue
относится к замкнутому циклу, и ваш код должен быть эквивалентен (избегая таких инструкций перехода):
while (something = get_something()) {
if (something == A || something == B)
do_something();
}
Но если вы ожидаете, что break
выйдет из цикла, как предлагает ваш комментарий (он всегда снова пытается с другим чем-то, пока он не примет значение false), вам понадобится другая структура.
Например:
do {
something = get_something();
} while (!(something == A || something == B));
do_something();
Ответ 2
Да, это нормально - это просто как использование в инструкции if
. Конечно, вы не можете использовать break
для выхода из цикла изнутри коммутатора.
Ответ 3
Да, continue будет игнорироваться оператором switch и перейдет в состояние проверяемого цикла.
Я хотел бы поделиться этой выдержкой из справочника по языку программирования C от Ричи:
Оператор continue
относится к break
, но используется реже; он вызывает следующую итерацию включающего цикла for
, while
или do
. В while
и do
это означает, что тестовая часть выполняется немедленно; в for
управление переходит к шагу приращения.
Оператор continue применяется только к циклам, но не к оператору switch
. continue
внутри switch
внутри цикла вызывает следующую итерацию цикла.
Я не уверен в этом для C++.
Ответ 4
Синтаксически корректно и стилистически хорошо.
Хороший стиль требует, чтобы каждый оператор case:
заканчивался одним из следующих:
break;
continue;
return (x);
exit (x);
throw (x);
//fallthrough
Кроме того, сразу после case (x):
с
case (y):
default:
допустимо - объединение нескольких случаев, имеющих точно такой же эффект.
Любое другое подозревается как ошибка, так же, как if(a=4){...}
Конечно, для работы continue
вам понадобится замкнутый контур (while
, for
, do...while
). Он не будет возвращаться обратно к case()
. Но конструкция вроде:
while(record = getNewRecord())
{
switch(record.type)
{
case RECORD_TYPE_...;
...
break;
default: //unknown type
continue; //skip processing this record altogether.
}
//...more processing...
}
... все в порядке.
Ответ 5
Несмотря на техническую достоверность, все эти скачки скрывают поток управления, особенно оператор continue
.
Я бы использовал такой трюк как последнее средство, а не первое.
Как насчет
while (something = get_something())
{
switch (something)
{
case A:
case B:
do_something();
}
}
Он короче и выполняет свои действия более четко.
Ответ 6
Это может быть мегабит в конце, но вы можете использовать continue 2
.
Некоторые сборки/конфиги php выведут это предупреждение:
Предупреждение PHP: переключение таргетинга "продолжить" эквивалентно "прерыванию". Вы хотели использовать "продолжить 2"?
Например:
$i = 1;
while ($i <= 10) {
$mod = $i % 4;
echo "\r\n out $i";
$i++;
switch($mod)
{
case 0:
break;
case 2:
continue;
break;
default:
continue 2;
break;
}
echo " is even";
}
Это выведет:
out 1
out 2 is even
out 3
out 4 is even
out 5
out 6 is even
out 7
out 8 is even
out 9
out 10 is even
Протестировано с PHP 5.5 и выше.
Ответ 7
Переключатель не считается циклом, поэтому вы не можете использовать Продолжить внутри оператора case в коммутаторе...