Компания ALT Linux
Опубликован: 10.04.2015 | Доступ: свободный | Студентов: 763 / 0 | Длительность: 14:03:00
Специальности: Программист, Преподаватель
Лекция 3:

Операторы управления

3.4.2 Оператор варианта case

Оператор варианта case необходим в тех случаях, когда в зависимости от значений какой-либо переменной надо выполнить те или иные операторы.

case выражение of
	значение_1 : оператор_1;
	значение_2 : оператор_2;
	...
	значение_N : оператор_N
else
	альтернативный_оператор
end;

Здесь выражение — переменная перечислимого типа (включая char и boolean), значение_1, значение_2,..., значение_N — это конкретное значение управляющей переменной или выражение, при котором необходимо выполнить соответствующий оператор, игнорируя остальные варианты. Значения в каждом наборе должны быть уникальны, то есть они могут появляться только в одном варианте. Пересечение наборов значений для разных вариантов является ошибкой.

Оператор работает следующим образом. Вычисляется значение выражения. Затем выполняется оператор, помеченный значением, совпадающим со значением выражения. То есть, если выражение принимает значение_1, то выполняется оператор_1. Если выражение принимает значение_2, то выполняется оператор_2 и так далее. Если выражение не принимает ни одно из значений, то выполняется альтернативный_оператор, расположенный после ключевого слова else.

Альтернативная ветвь else может отсутствовать, тогда оператор имеет вид:

case выражение of
	значение_1 : оператор_1;
	значение_2 : оператор_2;
	...
	значение_N : оператор_N;
end;

Кроме того, в операторе case допустимо использование составного оператора. Например:

case выражение of
	значение_1 : begin оператор_A; оператор_B; end;
	значение_2 : begin оператор_C; оператор_D; оператор_E; end;
	...
	значение_N : оператор_N;
end;

Рассмотрим применение оператора варианта на следующих примерах.

ЗАДАЧА 3.7. Вывести на печать название дня недели, соответствующее заданному числу D, при условии, что в месяце 31 день и первое число — понедельник.

Для решения задачи воспользуемся операцией mod, позволяющей вычислить остаток от деления двух чисел, и условием, что первое число — понедельник. Если в результате остаток от деления (обозначим его R) заданного числа D на семь будет равен единице, то это понедельник, двойке — вторник, тройке — среда и так далее. Следовательно, при построении алгоритма необходимо использовать семь условных операторов, как показано на рис. 3.18.

Решение задачи станет значительно проще, если при написании программы воспользоваться оператором варианта:

var d : byte;
begin
	write ( ’Введите число D= ’ );
	readln (D);
	case D mod 7 of {Вычисляется остаток от деления D на 7.}
		{В зависимости от полученного значения}
		{на печать выводится название дня недели}
		1 : writeln ( ’ПОНЕДЕЛЬНИК ’ );
		2 : writeln ( ’ВТОРНИК ’ );
		3 : writeln ( ’СРЕДА ’ );
		4 : writeln ( ’ЧЕТВЕРГ ’ );
		5 : writeln ( ’ПЯТНИЦА ’ );
		6 : writeln ( ’СУББОТА ’ );
		0 : writeln ( ’ВОСКРЕСЕНЬЕ ’ );
	end;
end.
Алгоритм решения задачи 3.7

увеличить изображение
Рис. 3.18. Алгоритм решения задачи 3.7

В предложенной записи оператора варианта отсутствует ветвь else. Это объясняется тем, что переменная R может принимать только одно из указанных значений, т. е. 1, 2, 3, 4, 5, 6 или 0.

ЗАДАЧА 3.8. По заданному номеру месяца m вывести на печать название времени года.

Для решения данной задачи необходимо проверить выполнение четырёх условий. Если заданное число m равно 12, 1 или 2, то это зима, если m попадает в диапазон от 3 до 5, то весна; лето определяется принадлежностью числа m диапазону от 6 до 8, и, соответственно, при равенстве переменной m 9, 10 или 11 это осень. Понятно, что область возможных значений переменной m находится в диапазоне от 1 до 12, и если пользователь введет число, не входящее в этот интервал, то появится сообщение об ошибке. Для этого в операторе case программы предусмотрена альтернативная ветка else.

var m: byte;
begin
	write ( ’Введите номер месяца m= ’ ); readln (m);
	//Проверка области допустимых значений переменной m.
	case m of
	//В зависимости от значения m на печать
	//выводится название времени года.
	1 2, 1, 2 : writeln ( ’ЗИМА ’ ); }
	3.. 5 : writeln ( ’ВЕСНА ’ ); }
	6.. 8 : writeln ( ’ЛЕТО ’ ); }
	9.. 1 1 : writeln ( ’ОСЕНЬ ’ )}
	//Если значение переменной m выходит за пределы области
	//допустимых значений, то выдается сообщение об ошибке.
	else writeln ( ’ОШИБКА ПРИ ВВОДЕ ! ! ! ’ );
	end
end.

3.4.3 Обработка ошибок. Вывод сообщений в среде Lazarus

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

Если пользователь допустил ошибку, например, при вводе данных, его необходимо проинформировать об этом. Для этого можно воспользоваться функцией MessageDlg, которая выводит сообщение в отдельном окне. В общем виде функцию записывают так:

MessageDlg (сообщение, тип_сообщения, [ список_кнопок ], справка );

где

  • сообщение — текст, который будет отображён в окне сообщения;
  • тип_сообщения — определяет внешний вид окна (табл. 3.2);
  • список_кнопок — константы (перечисляются через запятую), определяющие тип кнопок окна сообщения (табл. 3.3);
  • справка — номер окна справочной системы, которое будет выведено на экран, если нажать F1; параметр равен нулю, если использование справки не предусмотрено.
Таблица 3.2. Тип окна сообщения
Параметр Тип окна сообщения
mtInformation информационное
mtWarning предупредительное
mtError сообщение об ошибке
mtConfirmation запрос на подтверждение
mtCustom обычное
Таблица 3.3. Тип кнопки в окне сообщения
Константа Кнопка
mbYes Да
mbNo Нет
mbOk Ок
mbCancel Отмена
mbAbort Прервать
mbRetry Повторить
mbIgnore Пропустить
mbHelp Помощь
Конструирование формы для решения квадратного уравнения

Рис. 3.19. Конструирование формы для решения квадратного уравнения

Вернёмся к задаче решения квадратного уравнения (задача 3.3). Нами был рассмотрен алгоритм решения этой задачи и написана программа на языке программирования Free Pascal. Реализуем эту задачу в среде Lazarus.

Создадим новый проект6Подробно о создании проекта см. в главе 1.(рис. 3.19).

Для организации ввода коэффициентов уравнения внедрим на форму четыре объекта типа надпись (Label1, Label2, Label3, Label4) и три поля ввода (Edit1, Edit2, Edit3). Корни уравнения или сообщение об их отсутствии будем выводить в надпись Label57На этапе конструирования формы сделаем метку Label5 невидимой, для чего свойство Visible установим в false (Label5.Visible:=false).. Все действия по вычислению корней квадратного уравнения будут выполняться при нажатии кнопки Button1.

При вводе данных в программе могут возникнуть следующие ошибки:

  • в поле ввода оказалась строка, которую невозможно преобразовать в число;
  • значение коэффициента a равно нулю8При вычислении корней произойдёт деление на ноль..

Для того чтобы не допустить подобные ошибки, необходимо контролировать данные, вводимые пользователем. Применим для этой цели встроенную процедуру Val(S,X,Kod), которая преобразовывает строку S в число. Тип этого числа (целое или вещественное) зависит от типа переменной X. Если преобразование прошло успешно, то параметр Kod принимает значение, равное нулю, а результат преобразования записывается в переменную X. В противном случае Kod содержит номер позиции в строке S, где произошла ошибка, и содержимое переменной X не меняется. Далее приведён фрагмент программы с подробными комментариями:

procedure TForm1. Button1Click ( Sender : TObject );
var
	a, b, c, d, x1, x2 : real;
	kod1, kod2, kod3 : integer;
begin
	//Ввод значений коэффициентов квадратного уравнения.
	//Из поля ввода Edit1 считывается строка символов и
	//преобразовывается в вещественное число,
	//если преобразование прошло успешно, то kod1=0 и
	//полученное число записывается в переменную a.
	val ( Edit1. Text, a, kod1 );
	val ( Edit2. Text, b, kod2 );
	val ( Edit3. Text, c, kod3 );
	//Если преобразования прошли успешно, то
	if ( kod1=0) and ( kod2=0) and ( kod3=0) then
		//проверить чему равен первый коэффициент.
		//Если значение первого коэффициента равно нулю, то
			if a=0 then //выдать соответствующее сообщение.
				MessageDlg ( ’Введите не нулевое значение а ’,
					mtInformation, [ mbOk], 0 )
		else //иначе перейти к решению квадратного уравнения
		begin
			d:=b * b-4*a*c;
			Label5. Visible := true;
			if d<0 then
				Label5. Caption := ’В уравнении ’
					+chr (13)+ ’нет действительных корней ’
			else
			begin
				x1:=(-b+sqrt ( d ) ) / 2 / a;
				x2:=(-b-sqrt ( d ) ) / ( 2 * a );
				Label5. Caption := ’X1= ’+FloatToStr ( x1 )
					+chr (13)+ ’X2= ’+FloatToStr ( x2 );
			end;
		end
	else //Преобразование не выполнено, выдать сообщение.
	MessageDlg ( ’Введите числовое значение ’,
			mtInformation, [ mbOk ], 0 );
end.
Обработка ошибки ввода данных — коэффициент a равен 0

Рис. 3.20. Обработка ошибки ввода данных — коэффициент a равен 0

Решение квадратного уравнения 3x^2+4x+5=0

Решение квадратного уравнения(корней нет)

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

Рис. 3.22. Обработка ошибки ввода данных — в поле ввода строка, которую невозможно преобразовать в число
Вычисление корней квадратного уравнения

Рис. 3.23. Вычисление корней квадратного уравнения

Результаты работы программы показаны на рис. 3.20,рис. 3.21,рис. 3.22,3.23.

Метод обработки ошибок ввода, изложенный в этом примере, не единственный. Можно попытаться контролировать символы, поступающие в поля ввода. Набор символов, которые могут быть преобразованы в число, невелик. Это все цифры от 0 до 9, знак минус и символ запятой. Кроме того, пользователь должен иметь возможность удалять символы из поля ввода. Для этого ему понадобится клавиша BackSpace (#8 — символ с кодом восемь). Представим набор перечисленных символов в виде множества, и если окажется, что введённый символ не принадлежит ему, то будем выводить сообщение об ошибке при вводе.

Возможность контролировать ввод символов обеспечивает событие OnKeyPress. Если выделить компонент Edit2 и на вкладке инспектора объектов дважды щёлкнуть возле события нажатия клавиши OnKeyPress, то будет создана процедура обработки этого события. Текст процедуры с комментариями:

//Обработка события ввод символа в поле Edit2.
procedure TForm1. Edit2KeyPress ( Sender : TObject;
		var Key : Char );
begin //Если символ не принадлежит
		//множеству допустимых символов,то
	if not ( Key in [#8, ’, ’, ’_ ’, ’ 0 ’.. ’ 9 ’ ] ) then
	begin //выдать сообщение и
		MessageDlg ( ’Введите числовое значение ’,
			mtInformation, [ mbOk ], 0 );
		Abort; //прервать выполнение подпрограммы.
end; end.
Юрий Шутиков
Юрий Шутиков

По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. 
 

Евгений Силуков
Евгений Силуков

Еще в декабре выполнил тест №1, а его все так и не проверили.