Подтвердить что ты не робот

Использование продолжения в инструкции 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 и С++ отличаются от их поведения?

4b9b3361

Ответ 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 в коммутаторе...