По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. |
Операторы управления
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;
Рассмотрим применение оператора варианта на следующих примерах.
Для решения задачи воспользуемся операцией 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.
В предложенной записи оператора варианта отсутствует ветвь else. Это объясняется тем, что переменная R может принимать только одно из указанных значений, т. е. 1, 2, 3, 4, 5, 6 или 0.
Для решения данной задачи необходимо проверить выполнение четырёх условий. Если заданное число 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; параметр равен нулю, если использование справки не предусмотрено.
Параметр | Тип окна сообщения |
---|---|
mtInformation | информационное |
mtWarning | предупредительное |
mtError | сообщение об ошибке |
mtConfirmation | запрос на подтверждение |
mtCustom | обычное |
Константа | Кнопка |
---|---|
mbYes | Да |
mbNo | Нет |
mbOk | Ок |
mbCancel | Отмена |
mbAbort | Прервать |
mbRetry | Повторить |
mbIgnore | Пропустить |
mbHelp | Помощь |
Вернёмся к задаче решения квадратного уравнения (задача 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.
Решение квадратного уравнения
Рис. 3.22. Обработка ошибки ввода данных — в поле ввода строка, которую невозможно преобразовать в число
Результаты работы программы показаны на рис. 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.