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

Что означает оператор запятой в инструкции switch?

Мне задали вопрос, и мне было предложено дать результат.

int main(void){  
    int x = 2;  
    switch(x){  
        case 1,2,1: printf("Case 1 is executed");  
            break;  
        case 2,3,1: printf("Case 2 is executed");  
            break;  
        default : printf("Default case us executed");  
    }  
    return 0;  
}

Вышеприведенный код дает результат как "Случай 1 выполняется" в Turbo C, но в кодовых блоках и компиляции в Интернете он дает ошибку компилятора.

Какой из них правильный? Это ошибка компилятора или нет? А если нет, то почему код работает только на Turbo C?

4b9b3361

Ответ 1

это ошибка компилятора или нет.

Код недействителен в обоих языках: выражение case должно быть константным выражением, а константное выражение не может содержать запятую. (В C это указано явно, в С++ вы должны разблокировать грамматику, чтобы найти, что константное выражение должно быть условным выражением, которое не может содержать запятую).

Даже если вам было разрешено использовать оператор запятой здесь, оператор switch все равно будет недействительным, поскольку два случая будут иметь одинаковое значение, 1.

И если нет, то почему код работает только на турбо C.

Поскольку оба языка сильно изменились с тех пор, как последний доисторический компилятор был последним обновлен. Не используйте его, если вы хотите изучить варианты C или С++ с этого века.

Ответ 2

Что означает оператор запятой в инструкции switch? Это означает, что у вас старый компилятор.

Редактировать сообщение (чтобы показать пример case range)

Первые два примера (включая ваш исходный код) демонстрируют неправильный синтаксис оператора оператора (с пояснениями). В третьем примере кода показано, как метки ярлыков стеков выполняются правильно:

В вашем коде компилятор должен был помечать первую запятую после case 1, < - here

#include <ansi_c.h>
int main(void){  
    int x = 2;  
    switch(x)
    {  
        case 1,2,1: printf("Case 1 is executed");  
        break;  //error flagged at first comma, and all comma after in case
        case 2,3,1: printf("Case 2 is executed");  
        break;  
        default : printf("Default case is executed");  
    }  
    return 0;  
}  

И, даже модифицированный таким образом, вы также должны получить дублируемую метку:

#include <ansi_c.h>
int main(void){  
    int x = 2;  
    switch(x)
    {  
        case 1:
        case 2:
        case 1: printf("Case 1 is executed"); //duplicate label 1 error. (and others below) 
            break;  
        case 2:
        case 3:
        case 1: printf("Case 2 is executed");  
            break;

        default : printf("Default case is executed");  
    }
    return 0;  
}

Этот пример совершенно легален (C99, C11) и полезен: т.е. нет дубликатов ярлыков, а синтаксис соответствует правильному использованию коммутатора путем укладки уникальных меток для обработки условий, в которых case 1: OR case 2: OR case 3: следует обрабатывать одинаково (в том же блоке). И, конечно же, это верно и для случаев 4, 5 и 6.

#include <ansi_c.h>
int main(void){  
    int x = 2;  
    switch(x)
    {  
        case 1:
        case 2:
        case 3: printf("Case 1,2 or 3 is executed"); //duplicate label 1 error. (and others below) 
            break;  
        case 4:
        case 5:
        case 6: printf("Case 4,5 or 6 is executed");  
            break;
    }
    getchar();
    return 0;  
}

Этот последний пример включен только для полноты. Он иллюстрирует выражение case range. Несмотря на интерес к программистам C, он еще не является частью C99 или C11, скорее является расширением Sun (вкус unix) и компилятор GNU C (и др.):

...
    switch(x)
    {  
            case 'a' ... 'z':  //note: spaces between all characters ('a') and ellipses are required
                    printf("lowercase alpha char detected");
                    break;
            case 'A' ... 'B':
                    printf("uppercase alpha char detected");
                    break;

            default: printf("Default case is executed");  
    }
...

Причина для неоднозначных результатов, которые вы видите от одного компилятора к другому, может заключаться в том, что Turbo C действительно очень старый. Версия, которую вы используете, скорее всего, была реализована в отношении версии стандартов C, которая больше не актуальна.

Рассмотрим переход к текущему компилятору. Недорогая (бесплатная) альтернатива - MinGW. MinGW - очень хороший, с открытым исходным кодом компилятор. Если вам нравится использовать Integrated Development Environments (IDE), Code:: Blocks - это один из вариантов, также бесплатный, и как опция поставляется в комплекте с MinGW.

Что касается совместимости, найдите Сравнение с другими комнатами компилятора по этой ссылке: читайте о расширениях MinGW. MinGW расширения, расширяя возможности, иногда делают код написанным, используя их не переносимыми с другими текущими компиляторами. При использовании рекомендуется соблюдать осторожность.

Ответ 3

Turbo C использует оператор запятой на корпусах коммутатора и берет последнее значение, например, случай 1, 2, 3: будет скомпилирован как случай 3: случай 2, 3, 1 как случай 1: следовательно, Turbo C не даст вам любая ошибка. Если другие компиляторы не разрешат вам случай 1, 2, 3: вид самого заявления.

Но в вашем случае даже Turbo c даст ошибку, потому что аргументы case выглядят примерно так случай 1, 2, 1: и случай 3, 2, 1: который будет соблюден как случай 1: и случай 1: следовательно, в соответствии с правилами корпуса коммутатора вы можете иметь только один случай со значением, и вы не можете повторить случай

Я предпочитаю использовать gcc-компилятор скорее Turbo C

Ответ 4

это ошибка компилятора или нет.

Это вызовет ошибку компиляции (не знаю о TURBO С++, но в современных компиляторах).
Это не работает оператор switch (недопустимый синтаксис в c/С++). Вы не можете повторно использовать значение case в выражении switch (см. Ссылку , указанную chris). Как вы можете это сделать;

 switch(x){
            case 1: case 2: case 3: printf("Case 1 is executed");
            break;
            default : printf("Default case us execyted"); 
          }

Ответ 5

Вы не можете использовать дважды то же значение "case"
Это неверно: case 1: case 2: case 1: printf("Case 1 is executed");
Пытался скомпилировать на VS2010 = > (ошибка C2196: значение case '1' уже используется)

Ответ 6

FYI, сегодня можно использовать расширение расширения диапазона GCC, когда оно подходит (что не часто) для аналогичных результатов (поддерживаются только диапазоны, а не произвольные списки значений).

case 1 ... 5:
case 'A' ... 'Z':