while (cin >> ch) {
//
switch (ch) {
case 'a':
++aCnt;
break;
case 'e':
++eCnt;
break;
case 'i':
++iCnt;
break;
case 'o':
++oCnt;
break;
case 'u':
++uCnt;
break;
}
}
// вывод результата
cout << "Number of vowel a: \t" << aCnt << '\n'
<< "Number of vowel e: \t" << eCnt << '\n'
<< "Number of vowel i: \t" << iCnt << '\n'
<< "Number of vowel o: \t" << oCnt << '\n'
<< "Number of vowel u: \t" << uCnt << endl;
Оператор switch
вычисляет результат выражения, расположенного за ключевым словом switch
. Это выражение может быть объявлением инициализированной переменной (см. раздел 5.2). Выражение преобразуется в целочисленный тип. Результат выражения сравнивается со значением, ассоциированным с каждым оператором case
.
Если результат выражения соответствует значению метки case
, выполнение кода начинается с первого оператора после switch
, но оно может быть прервано оператором break
.
Более подробно оператор break
рассматривается в разделе 5.5.1, а пока достаточно знать, что он прерывает текущий поток выполнения. В данном случае оператор break
передает управление первому оператору после оператора switch
. Здесь оператор switch
является единственным оператором в теле цикла while
, поэтому его прерывание возвращает контроль окружающему оператору while
. Поскольку в нем нет никаких других операторов, цикл while
продолжается, если его условие выполняется.
Если соответствия не найдено, выполнение сразу переходит к первому оператору после switch
. Как уже упоминалось, в этом примере выход из оператора switch
передает управление условию цикла while
.
Ключевое слово case и связанное с ним значение называют также case
(case
label). Значением каждой метки case
является константное выражение (см. раздел 2.4.4).
char ch = getVal();
int ival = 42;
switch(ch) {
case 3.14: //
case ival: // ошибка:
// ...
Одинаковые значения меток case
недопустимы. Существует также специальная метка default
, рассматриваемая ниже.
switch
Важно понимать, как управление передается между метками case
. После обнаружения соответствующей метки case
выполнение начинается с нее и продолжается далее через все остальные метки до конца или пока выполнение не будет прервано явно. Во избежание выполнения последующих разделов case
выполнение следует прервать явно, поэтому оператор break
обычно является последним оператором перед следующей меткой case
.
Однако возможны ситуации, когда необходимо именно стандартное поведение оператора switch
. У каждой метки case
может быть только одно значение, однако две или более метки могут совместно использовать единый набор действий. В таких ситуациях достаточно пропустить оператор break
и позволить программе пройти несколько меток case
.
Например, можно было бы посчитать общее количество гласных так:
unsigned vowelCnt = 0;
// ...
switch (ch) {
//
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
++vowelCnt;
break;
}
Здесь расположено несколько меток case
подряд без оператора break
. Теперь при любой гласной в переменной ch
будет выполняться тот же код.
Поскольку язык С++ не требует обязательно располагать метки case
в отдельной строке, весь диапазон значений можно указать в одной строке:
switch (ch) {
//
case 'a': case 'e': case 'i': case 'o': case 'u':
++vowelCnt;
break;
}
break
пропускают преднамеренно, довольно редки, поэтому их следует обязательно комментировать, объясняя логику действий.
break
— весьма распространенная ошибкаВесьма распространено заблуждение, что выполняются только те операторы, которые связаны с совпавшей меткой case
. Вот пример неправильной реализации подсчета гласных в операторе switch
:
//
switch (ch) {
case 'a' :