Статья
Версия для печати
Обсудить на форуме
Урок C/C++ № 11. Структура множественного выбора.


Урок 11. Структура множественного выбора.

Предыдущий урок

Заглянем в предыдущий урок. Там мы закончили разбираться тем, что же можно сделать с помощью оператора if, если нужно проверить не одно, а несколько условий сразу. Пожалуй, я повторю пример, который мы там разобрали для большей наглядности.
Код: (C)
     char ZNAC;
     int x,y,z;

      if (ZNAC == '-') x = y - z;
      else  if (ZNAC == '+') x = y + z;
            else if (ZNAC == '*') x = y * z;
                  else if (ZNAC == '/') x = y / z;
                        else ...
Вспомнили? Получилась такая себе лесенка из вложенных в друг друга операторов if.
Сегодня мы рассмотрим другую, родственную управляющую структуру: структуру множественного выбора. Оператор структуры множественного выбора  называется switch. Такая структура тоже в конечном итоге структура ветвления, но если if это разделение пути надвое (да - мы идем в одну сторону, нет - в другую), то switch это разветвление на большее число вариантов, нежели 2. Ивана-царевича вспомнили? Налево пойдешь - по голове получишь, но жив останешься, направо пойдешь - коня потеряешь, ну а если прямо пойдешь сами помните. Собственно это типичный вариант структуры множественного выбора.
Теперь посмотрим, как он работает.
Естественно, необходимость проверять условия никуда не девается, но выглядит это синтаксически иначе, чем для оператора if. Давайте пример, который мы повторили выше перепишем, используя оператор switch.
Код: (C)
switch (ZNAC)
{
case -:
        x=y-z;
        break;

case +:
        x=y+z;
        break;

case *:
        x=y*z;
        break;

case /:
        x=y/z;
        break;

default:
        cout<<А куркулятор у меня только арифметический! Чего это вы тут такое левое нажимаете?;
        break;
}
А теперь разбираемся. Сразу после оператора switch идет в круглых скобках имя переменной, которая проверяется на соответствие определенному значению (в этих скобках может стоять и выражение). Так называемое управляющее выражение. Т.е. условие, которое для оператора if записывается в скобках (например, ZNAC=-) как бы делится на 2 части: первая остается в скобках после оператора switch, вторая (значение) выносится ниже и устанавливается после ключевого слова case. Знак сравнения (не любой, а только конкретно - знак равенства) подразумевается сам по себе, так как он один и других зесь просто быть не может.
Внимание! В Си в структуре множественного выбора можно использовать (т.е. подразумевать, как мы выяснили выше) ТОЛЬКО оператор сравнения ==. Никакие другие операторы сравнения использоваться не могут! Вернемся к этому немного позже.
С первой строчкой разобрались. Дальше - case. Расшифровывается так: в случае, если указанные после switch в скобках переменная или выражение принимают такое значение, как указанные case, то начинают выполняться операторы, следующие после этого же case, если нет - мы переходим к другому случаю, к другому case. Если среди всех описанных нами случаев нет ни одного, соответствующего текущему значению проверяемой переменной или выражениия, переходим к служебному слову default. В этом случае начинают выполняться операторы, находящиеся после него. Собственно, этого служебного слова в данной конструкции может и не быть - оно не обязательно, но считается правильным все же описывать ситуации, которые вы не предвидели в case. Кроме того, default не обязательно должен располагаться в самом конце рассматриваемой структуры, но рекомендуется все-таки располагать его именно там - как-то логически более на месте. Но если вам все-таки очень захотелось втемышить его куда-нибудь посередине, не забудьте после операторов, описывающих действия по умолчанию поставить break. Зачем - смотрите следующий абзац.
Теперь рассмотрим оператор break. Когда выполняется этот оператор, следущие за ним строки не выполняются, программа выходит из блока структуры и начинает выполняться оператор, следующий сразу после данного блока. Простым языком говоря: если представлять блок структуры, как контейнер (что собственно так и есть), как только встретили break, из контейнера выбрались и пошли дальше по коду.
Оператор break здесь необходим после операторов действия для каждого случая, кроме самого последнего (обычно это действия по умолчанию), т.к. в последнем случае программа по любому выходит из структуры switch. Но если вы и в этом случае поставите оператор break, ошибкой это являться не будет.
Я обещала вернуться к единственности оператора сравнения для структуры множественного выбора. В этом языке данная структура может применяться ТОЛЬКО для проверки на совпадение с константным целым выражением, т.е. это может быть любая комбинация символов и целых чисел, лишь бы они были постоянными. Следует отметить, что использование целого константного выражения является существенным недостатком, присущим рассмотренному оператору. ПОЭТОМУ: не пытайтесь лепить в switch проверку переменной или вызов функции, даже если она однозначно целая или символьная. Еще раз посторюсь: число, указанное для каждого конкретного случая НЕ МОЖЕТ ИЗМЕНЯТЬСЯ! Константы в вариантах case должны быть различными. Почему, надеюсь - ясно?
После ключевого слова switch может стоять и выражение в круглых скобках, может быть там любое выражение, допустимое в языке СИ, значение которого должно быть целым. Отметим, что можно использовать явное приведение к целому типу, однако необходимо помнить о тех ограничениях и рекомендациях, о которых говорилось в предыдущих уроках.
Символы должны заключаться в одиночные кавычки. Например: 'F'.
Если есть несколько случаев, для которых должны выполняться одни и те же действия, после case перечисляются все константы, а после идут общие для этих случаев операторы, описывающие действие. Выглядит так, например:
Код: (C)
сase D:
case d:
                //блок операторов
Еще некоторые детали данной структуры: список операторов может быть пустым, либо содержать один или более операторов. Причем в операторе switch не требуется заключать последовательность операторов в фигурные скобки. Однако наличие фигурных скобок - не ошибка.
В операторе switch можно использовать свои локальные переменные, объявления которых находятся перед первым ключевым словом case, однако в объявлениях не должна использоваться инициализация.
Наговорила много. Не запутались? Давайте уложим это все в некое подобие алгоритма:
Схема выполнения оператора switch следующая:
  • - вычисляется выражение в круглых скобках;
  • - вычисленные значения последовательно сравниваются с константными выражениями, следующими за ключевыми словами case;
  • - если одно из константных выражений совпадает со значением выражения, то управление передается на оператор, помеченный соответствующим ключевым словом case;
  • - если ни одно из константных выражений не равно выражению, то управление передается на оператор, помеченный ключевым словом default, а в случае его отсутствия управление передается на следующий после switch оператор.

В теле оператора switch можно использовать вложенные операторы switch, (или другие вложенные структуры) при этом в ключевых словах case можно использовать одинаковые константные выражения.
Пример:
Код: (C)
     switch (a)
      {
        case 1: b=c; break;
        case 2:
            switch (d)
            {
                case 0:  f=s;  break;

                case 1:  f=9;  break;

                case 2:  f-=9; break;
            }
         case 3: b-=c; break;
         :
      }
Ну-с, вроде все по этой теме. переходим к водным процедурам, т.е. заданиям.

Задания
  • Допустим, что книги в вашей библиотеке разделены по тематике на 4 отдела, Отделы обозначены буквами латинского алфавита: А, В, С, D. Вы их разбираете и заносите в компьютер метку отдела - вы посто хотите посчитать - сколько книг к какому разделу принадлежит. (Согласна - процедура явно притянута за уши, но на то это и учебное задание, чтоб быть слегка дебильным). При внесении метки отдела наращивается переменная-счетчик для данного отдела. При нажатии любой другой клавиши на экран выводится сообщение о том сколько книг по какому отделу уже насчитали на данный момент и сообщение: Хотите ли вы продолжить считать?. Если вы вводите 1, значит подсчет продолжается, -1 подсчет прекращается и программа заканчивает работу, что-то другое - программа говорит: Не въехало! Изъясняйтесь понятнее.
  • Напишите программу для любознательного, но туповатого путешественника, которая при наборе страны выдаст на экран столицу данной страны и количество народа, проживающего в ней. Данные для проги:
СтранаСтолицаНаселение (млн.чел.)
ВенгрияБудапешт11
ИталияРим60
ГрецияАфины10
ТурцияАнкара55
ЕгипетКаир53
НепалКатманду18
БельгияБрюссель10

На непредвиденные обстоятельста пусть пишет: Да не знаю я такой страны, вот пристали!
Версия для печати
Обсудить на форуме