Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык Си. Лабораторные работы / Справочник. Часть 1 (СПбГУТ).doc
Скачиваний:
50
Добавлен:
10.09.2019
Размер:
949.25 Кб
Скачать

2.2.2. Многовариантные разветвления

Будем считать, что набор возможных действий при организации многовариантных разветвлений содержит более двух действий.

Организация многовариантных разветвлений в языке Си может выполняться с помощью следующих средств:

● переключателя switch,

● нескольких инструкций if.

Наиболее удобным средством организации сложных разветвлений является использование инструкции switch. К сожалению, возможности этой инструкции в языке Си ограничены. Одним из наиболее перспективных способов организации сложных разветвлений в тех случаях, когда применение переключателя switch невозможно, является моделирование работы переключателя с помощью вложенных инструкций if.

Вначале рассмотрим пример, в котором для организации сложного разветвления используется переключатель switch. При этом представляет интерес исследовать особенности переключателя switch, которые обеспечивают удобство его использования. Затем будут рассмотрены возможные варианты моделирования этой инструкции с помощью вложенных инструкций if.

2.2.2.1. Использование переключателя switch

Постановка задачи.

Написать простейший калькулятор для выполнения четырёх арифметических действий.

Решение.

Определим состав входных и выходных данных для разрабатываемой программы. К ним, очевидно, можно отнести два операнда выполняемой операции, а также её оператор (знак операции). Для повышения общности решения будем считать операнды вещественными числами, выбрав для их представления в программе тип double. В связи с тем, что на клавиатуре имеются клавиши, соответствующие обычным знакам арифметических действий (+ , – , / , *), в качестве типа для представления оператора выберем тип char. Для повышения читабельности программы выберем для переменных, предназначенных для представления исходных данных, следующие имена: first и second – для операндов и operator – для оператора. Для результата вычислений будем использовать переменную result типа double.

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

Определим набор действий, из которого следует сделать выбор:

result = first + second; result = first – second; result = first * second; result = first / second; printf(“неправильный знак операции \n”);

Для выбора требуемого действия целесообразно использовать переключатель switch, в котором в качестве селектора использовать переменную operator. Переключатель switch должен содержать пять ветвей. Четыре ветви должны соответствовать штатным ситуациям, а последняя, выводящая сообщение о неправильном вводе оператора, соответствует нештатной ситуации. Вначале должны следовать ветви для штатных ситуаций. Последней должна быть записана с меткой default ветвь, соответствующая нештатной ситуации. Каждая штатная ветвь должна заканчиваться инструкцией break. Это необходимо для предотвращения “провала” в следующую ветвь. Нештатная ветвь должна заканчиваться инструкцией return. Это позволит завершить выполнение программы после вывода сообщения об ошибке ввода. Учитывая всё сказанное, получим следующий текст программы.

#include<stdio.h> #include<conio.h> int main(void) { double first, second, result; char operator; printf(“Введите значение первого операнда =”); scanf(“%lf”, &first); printf(“Введите значение второго операнда =”); scanf(“%lf%*c”, &second); printf(“Требуемая операция =”); scanf(“%c”, &operator) ; switch(operator) { case ‘+’ : result = first + second; break; case ‘-’ : result = first - second; break; case ‘*’ : result = first * second; break; case ‘/’ : result = first / second; break ; default : printf(“Некорректная операция \n”); return 1; } printf(“Результат выполнения операции = %0.4g\n”, result); getch(); return 0; }

Отметим одну особенность, которую следует учитывать при совместном вводе чисел и данных символьного типа. После ввода числа в буфере клавиатуры остаётся символ новой строки (\n). Этот символ может быть прочитан последующим вызовом функции scanf() в том случае, когда этот вызов используется для ввода переменной типа char. Для удаления этого символа из буфера клавиатуры во втором вызове функции scanf() введена дополнительная спецификация типа %c, предназначенная для чтения данных символьного типа. Символ *, расположенный между символами % и c, является указанием для компилятора, что прочитанный символ не надо записывать в память.

Остановимся на особенностях переключателя switch, которые обеспечивают удобство его использования:

▪ каждое из выбираемых действий в исходном тексте встречается только один раз,

▪ каждое из выбираемых действий выполняется только один раз,

▪ после выполнения выбранного действия работа переключателя switch прекращается,

▪ выбранное действие располагается рядом с условием, определяющим его выбор,

▪ порядок следования ветвей, соответствующих штатным ситуациям не влияет на корректность разветвления.

Особенность рассмотренной задачи состоит в том, что при её программировании удаётся легко найти селектор, необходимый для построения переключателя switch. Возникает вопрос, как быть в тех случаях, когда такой селектор не удается найти. Частичным ответом на этот вопрос является построение конструкций, позволяющих реализовать перечисленные выше свойства переключателя switch, например, с помощью вложенных инструкций if.