#c #switch-statement
#c #switch-statement
Вопрос:
Я работал с оператором Switch, когда случайно написал следующий фрагмент кода (на gcc в C)
int a = 2;
switch(a)
{
default:
printf("Defaultn");
case 1:
printf("Onen");
case2 :
printf("Twon");
}
Результат, который я получил, был:
По умолчанию
Один
Два
Я могу понять, как возник этот результат, однако я не понимаю, почему это не выдает ошибку, я имею в виду, что у меня явно нет метки случая (в случае 2), верно? Также я наблюдал тот же результат, если, например, я исправил «case2» как «casex». В то время как, если я не помещаю ни в одну метку case, это выдает ошибку времени компиляции.
Любая помощь будет оценена, спасибо!
Комментарии:
1. Не
case2:
выдает вам предупреждение компилятора? Ваш запрос касается отсутствия там пробела или отсутствияbreak
ожидаемых операторов?2.
case2
является допустимой меткой; это просто неcase
метка с точки зрения области действияswitch
оператора. Без abreak
он просто игнорируется.3. Предупреждение, которое я получил (от MSVC), было предупреждением C4102: ‘case2’: метка без ссылок.
4. Вы должны вставить
break
оператор после кода каждогоcase
.5. > Предупреждение, которое я получил (от MSVC), было предупреждением C4102: ‘case2’: метка без ссылок. Как упоминал Марк Беннингфилд,
case2 :
это «обычная» метка (для goto), а неcase
ключевое слово. Это предупреждение указываетgoto case2;
на то, что в вашей программе нет оператора … результатом здесь являетсяcase2 :
не случай для вашего коммутатора, это просто метка goto внутри блока switch.
Ответ №1:
Я могу понять, как возник этот результат, однако я не понимаю, почему это не выдает ошибку, я имею в виду, что у меня явно нет метки случая (в случае 2), верно?
Да, case2 :
это не метка регистра, но это допустимая действительная обычная метка. Любому оператору может предшествовать такая метка. Поскольку вы используете GCC, вы могли бы рассмотреть возможность включения этой -Wall
опции (или специально -Wunused-label
), и в этом случае GCC должен предупредить, что эта метка не используется (поскольку она не является целью какого-либо goto
оператора).
Также я наблюдал тот же результат, если, например, я исправил «case2» как «casex».
Ну, конечно. casex :
также является допустимой обычной меткой.
В то время как, если я не помещаю ни в одну метку case, это выдает ошибку времени компиляции.
Я полагаю, вы должны иметь в виду, что вы оставляете двоеточие, но удаляете весь текст метки ( case2
/ casex
). Это действительно привело бы к недопустимому коду. Однако, если вы удалили всю строку, тогда, конечно, это было бы хорошо.
Комментарии:
1. Извиняюсь, под меткой no case я имел в виду просто написание «case». Прочитав ваш ответ, я бы предположил, что, поскольку регистр является зарезервированным словом, он выдает ошибку, поскольку сам по себе он не является возможной меткой, и компилятор обрабатывает его как метку регистра переключателя и требует после нее номер.
2. Да, @KartikRamesh
case
зарезервировано для использования в качестве ключевого слова, поэтомуcase :
не является ни допустимой обычной меткой, ни допустимой меткой регистра.
Ответ №2:
вы пропустили break
, поэтому выполнение продолжается после каждого случая (но с a != 1, чтобы иметь эти 3 выхода)
примечание case2:
рассматривается как метка (для goto), поэтому не является ошибкой
Комментарии:
1. Я думаю, OP это знает.
2. @WeatherVane ах да, я читаю быстро… на самом деле я прочитал только начало, прежде чем ответить, позор мне ^^
3. Сначала я подумал,
case2
что это опечатка, но она повторяется в теле вопроса.4. @WeatherVane да, я понимаю… когда я решил прочитать вопрос, а не только код ^^
Ответ №3:
Здесь происходит то, что вы получили метку по умолчанию, и поскольку у вас не было перерыва, вы выполнили все остальные случаи.