Что делать, если я не пишу по умолчанию в случае переключения?

int a = 10;
switch(a){
case 0:
    printf("case 0");
    break;
case 1:
    printf("case 1");
    break;
}

Приведенный выше код действителен?

Если я уверен, что int a не будет иметь никакого другого значения, кроме 1 и 0, могу ли я избежать default?

Что, если в любом случае значение будет отличаться от 1 и 0?

Я знаю, что это глупый вопрос, но я подумал, что, возможно, это будет незаконным или неопределенным поведением, поэтому я просто попросил убедиться.


person Jeegar Patel    schedule 05.11.2011    source источник
comment
я пытался, но я думал, что, возможно, это будет незаконным или неопределенным поведением, поэтому просто попросил убедиться   -  person Jeegar Patel    schedule 05.11.2011
comment
В таких случаях я всегда устанавливаю значение по умолчанию и выбрасываю исключение. Теперь в C#7 с большей гибкостью регистра, когда я перехожу к охвату всех возможных случаев и использую default для покрытия невозможных. Дуглас Адамс понял бы эту точку зрения.   -  person Paulustrious    schedule 21.05.2017
comment
Обычно я добавляю ASSERT(false);, чтобы обнаруживать неожиданные значения в сборках DEBUG.   -  person Phil1970    schedule 29.03.2018
comment
Прочтите docs.microsoft.com/en-us/dotnet /csharp/языковая ссылка/   -  person RJN    schedule 27.06.2018


Ответы (8)


Код действителен. Если метка default: отсутствует и ни одна из меток case не соответствует значению «переключатель», то ни один из контролируемых составных операторов не будет выполнен. Выполнение продолжится с конца оператора switch.

ИСО/МЭК 9899:1999, раздел 6.8.4.2:

[...] Если преобразованное константное выражение case не совпадает и отсутствует метка default, никакая часть тела переключателя не выполняется.

person CB Bailey    schedule 05.11.2011

Как указывали другие, это совершенно правильный код. Однако с точки зрения стиля кодирования я предпочитаю добавлять пустой оператор default с комментарием, чтобы было ясно, что я не забыл об этом случайно.

int a=10;
switch(a)
{
case 0: printf("case 0");
         break;
case 1: printf("case 1");
         break;
default: // do nothing;
         break;
}

Код, сгенерированный с/без default, должен быть идентичен.

person Praetorian    schedule 05.11.2011
comment
Если вы намерены обрабатывать все случаи в перечислении, я бы рекомендовал опускать регистр по умолчанию, потому что большинство компиляторов предупредят, если регистр перечисления будет забыт в операторе switch. - person rdb; 18.07.2016
comment
Было бы еще лучше иметь утверждение (или подобное), если вы ожидаете, что оно никогда не провалится. Таким образом можно поймать много ошибок. - person Peter Mortensen; 06.03.2021
comment
@rdb Большинство компиляторов? Разве это не IDE делает это? - person Kathir; 14.05.2021
comment
@Kathir, я не знаю, я не использую IDE. Эти предупреждения обычно генерируются компиляторами, но среда IDE может передать их разработчику. Вполне возможно, что в некоторых IDE есть собственные средства проверки кода, которые также предупреждают об этом разработчика. - person rdb; 15.05.2021
comment
@rdb Хорошо. Оба варианта возможны. Компилятор генерирует предупреждение во время компиляции. IDE выполняет нечто, называемое linting. Я не знаю внутренностей этого процесса линтинга. НО, я не думаю, что он компилирует код - person Kathir; 15.05.2021
comment
Возможно, было бы неплохо иметь предупреждение о забытых случаях перечисления, но если значение было передано через переменную/параметр, возможно ли, что неопределенные значения возникают во время выполнения? Как насчет переноса случая по умолчанию между #ifndef ENUM_COVERAGE_TEST ... #endif - person grenix; 18.05.2021

Это совершенно законный кодекс. Если a не равно ни 0, ни 1, то блок switch будет полностью пропущен.

person drdwilcox    schedule 05.11.2011

Допустимо отсутствие случая default.

Однако, даже если вы уверены, что у вас не будет никакого значения, кроме 1 и 0, хорошей практикой будет иметь случай по умолчанию, чтобы поймать любое другое значение (хотя это теоретически невозможно, это может появиться в некоторых случаях, например, при переполнении буфера) и вывести сообщение об ошибке.

person Igor Oks    schedule 05.11.2011
comment
Вы предполагаете, что несоответствие одному из операторов case является ошибкой - вероятно, в этом случае это так. Вы можете захотеть выполнить действие только с некоторыми возможными значениями переменной и просто продолжить в других случаях. ИМХО, это вполне разумное использование оператора switch. - person CB Bailey; 05.11.2011
comment
@Charles: Он написал в вопросе: посмотрите, уверен ли я, что int a не будет иметь никакого значения, кроме 1 и 0, то в этом случае я могу избежать значения по умолчанию: - person Igor Oks; 05.11.2011
comment
Я не спорил с вами, извините, если так получилось. Я просто указал на то, что, хотя, в целом, использование метки default является хорошей практикой, ее отсутствие не обязательно является плохой практикой. - person CB Bailey; 05.11.2011
comment
@CharlesBailey Кажется очень целесообразным включить случай по умолчанию, хотя бы по какой-либо другой причине, кроме документального подтверждения того, что вы, по крайней мере, рассматривали случай по умолчанию (даже если в нем нет исполняемого кода). Учитывая, что его включение дает относительно большую пользу, а его исключение не дает никаких реальных преимуществ, я бы сказал, что включать его — очень хорошая практика. - person weberc2; 20.11.2012
comment
@weberc2 есть есть преимущество, полученное от его исключения: если вы включаете перечисление, некоторые компиляторы предупредят, если значение перечисления пропущено в случае переключения. Это может быть очень полезным инструментом для поиска мест, где следует добавить регистр после добавления значения в перечисление. - person rdb; 18.07.2016

Да, приведенный выше код действителен.

Если условие переключателя не соответствует ни одному условию случая и значение по умолчанию отсутствует, выполнение программы продолжается, выходя из переключателя, ничего не делая.

person aleroot    schedule 05.11.2011

Значение по умолчанию не является обязательным, но всегда хорошо иметь его.

Код в идеале, а наша жизнь - нет, и нет ничего плохого в том, чтобы поставить там защиту. Это также поможет вам отладить, если произойдет что-то неожиданное.

person riveridea    schedule 05.01.2017

Это то же самое, что и no, если условие соответствует, а еще не указано.

default не является обязательным в случае переключения. Если ни один случай не соответствует и значение по умолчанию не указано, просто ничего не будет выполнено.

person RG1    schedule 29.04.2016

Синтаксис оператора switch в языке программирования C следующий:

switch(expression) {

   case constant-expression  :
      statement(s);
      break; /* optional */

   case constant-expression  :
      statement(s);
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
   statement(s);
}
person Arif    schedule 26.02.2019