Обработка ошибок времени исполнения




Наше приложение вполне работоспособно, пока пользователь выполняет "правильные" действия: вводит числа в разрешенном формате, производит разрешенные операции, например, не допускает деления на ноль, вычислений с недопустимо большими значениями, извлечения корня из отрицательного числа и т.п. Однако, стоит ему выйти за пределы допустимых действий, и выполнение программы будет прервано. В этом можно убедиться, загрузив приложение и нажав кнопку . Поскольку в окно ввода чисел первоначально мы помещаем 0, то программа завершиться аварийно с сообщением, показанным на Рис. 5.2.:

Окно сообщения об ошибке времени исполнения (Проект Project2.exe вызвал исключительную ситуацию класса EZeroDivide c сообщением 'Деление на ноль с плавающей точкой').

Это сообщение выводит визуальная среда Delphi. Для возврата в нее необходимо завершить проект, нажав комбинацию клавиш Ctrl-F2.

Наша задача состоит в том, чтобы максимально защитить приложение от результатов возникновения ИС. Для этого воспользуемся обработчиками ИС, принадлежащих иерархии классов Exception, а также оператором try… except. Надо сказать, что среда Delphi по умолчанию перехватывает все ИС, выводит собственное сообщение и останавливает выполнение проекта. Чтобы этого избежать снимем флажок "Stop On Delphi Exceptions" в диалоге Tools – Debugger Options… главного меню Delphi

 

Флажок перехвата ИС в настройках Delphi

Теперь, если мы не предусмотрим иного, обработка ИС будет выполняться стандартным обработчиком подсистемы времени исполнения Delphi.

Создадим собственную систему обработки ИС.

Начнем с процедуры обработки нажатия клавиш арифметических операций. Здесь возможно возникновение ИС, связанной

1) со вводом неправильного числа с плавающей точкой (EConvertError) и

2) со вводом слишком большого числа (EOverFlow – переполнение с плавающей точкой). В секцию try оператора обработки ИС поместим критичный с точки зрения возникновения ИС оператор

Value1:= StrToFloat(ValueEdit.text);

а в секции except предусмотрим два последовательных блока on…do, обрабатывающих обе возможные ИС:

procedure TForm1.SpeedButton1Click(Sender: TObject);

Begin

if ((Sender As TSpeedButton).Tag = 1) and (ValueEdit.SelStart = 0) then

Begin

ValueEdit.Text:= '-'+ValueEdit.text;

ValueEdit.SelStart:= 1;

Exit;

end;

Try

Value1:= StrToFloat(ValueEdit.text);

Except

on EOverFlow do

Begin

Showmessage('Переполнение!');

Value1:= 0;

ValueEdit.Text:= FloatToStr(Value1);

exit;

end;

on EConvertError do

Begin

Showmessage('Неверное число!');

Value1:= 0;

ValueEdit.Text:= FloatToStr(Value1);

exit;

end;

end;

SpeedButton16Click(Sender);

Oper:= (Sender As TSpeedButton).tag;

end;

Результатом обработки обоих ИС будет вывод соответствующего сообщения, присваивание первому операнду значения 0, вывод этого значения в текстовом блоке и досрочный выход из процедуры.

Займемся обработкой ИС, которые могут возникнуть при нажатии кнопки . Здесь могут возникнуть ИС:

1) ввод неправильного числа в качестве значения второго операнда (EConvertError);

2) переполнение с плавающей точкой (EOverFlow);

3) деление на ноль с плавающей точкой (EZeroDivide). (Возможна также ИС EUnderFlow – слишком маленькое число с плавающей точкой, "машинный ноль", однако, как правило, эта ИС некритична и не вызывает остановки программы.)

Обработаем две первых ИС во вложенных блоках try … except, а последнюю – при выполнении операции деления, где она может возникнуть.

Преобразуем код обработчика события OnClick кнопки :

procedure TForm1.SpeedButton18Click(Sender: TObject);

Begin

Try

Value2:= StrToFloat(ValueEdit.Text);

Try

case Oper of

0: Value1:= Value1 + Value2;

1: Value1:= Value1 - Value2;

2: Value1:= Value1 * Value2;

3:

Begin

Try

Value1:= Value1 / Value2;

Except

on EZeroDivide do

begin

Showmessage('Деление на ноль!');

Exit;

end;

end;

end;

end;

Except

on EOverFlow do

Begin

Showmessage('Переполнение!');

exit;

end;

end;

Except

on EConvertError do

Begin

Showmessage('Неверное число!');

Value2:= 0;

ValueEdit.Text:= FloatToStr(Value2);

exit

end;

end;

ValueEdit.Text:= FloatToStr(Value1);

end;

Напишем теперь обработчик ИС, которые могут возникнуть при нажатии клавиши . Здесь могут возникнуть две ИС:

1) неправильное число с плавающей точкой и

2) корень из отрицательного числа (EInvalidOp – неправильная операция с плавающей точкой, либо неверная инструкция процессора). Преобразованный код обработчика события OnClick для этой кнопки приведен ниже.

procedure TForm1.SpeedButton17Click(Sender: TObject);

Begin

Try

Value1:= StrToFloat(ValueEdit.text);

Except

on EConvertError do

Begin

Showmessage('Неверное число!');

Value1:= 0;

SpeedButton16Click(Sender);

Exit;

end;

end;

Try

Value1:= sqrt(Value1);

Except

on EInvalidOp do

Begin

Showmessage('Корень из отрицательного числа!');

Exit;

End

end;

ValueEdit.Text:= FloatToStr(Value1);

end;

 

Задание. Напишите аналогичные обработчики событий OnClick для кнопок и .

Указание. При обработке события OnClick для кнопки могут возникнуть ИС

1) неправильное число с плавающей точкой;

2) переполнение с плавающей точкой.

При обработке события OnClick для кнопки . могут возникнуть ИС

1) неправильное число с плавающей точкой;

2) переполнение с плавающей точкой; 3) деление на ноль.

Мы создали все обработчики ИС, которые могут возникнуть в результате выполнения нашего приложения, за исключением ситуации, когда в локализованной ("русской") версии ОС Windows в десятичной записи числа вместо точки установлена запятая. В этом случае в нашей программе ввод любого числа с дробной частью будет вызывать ИС EConvertError. Для того, чтобы этого избежать, при создании формы можно проверить какой символ используется в качестве разделителя и использовать именно его:

procedure TForm1.FormCreate(Sender: TObject);

Begin

Try

ValueEdit.Text:= '1.2';

Value1:= StrToFloat(ValueEdit.Text);

Except

on EConvertError do SpeedButton14.caption:= ',';

end;

 

value1:= 0;

value2:= 0;

ValueEdit.Text:= FloatToStr(Value1);

Oper:= -1;

end;

В процедуре при обнаружении ИС заголовок кнопки с десятичной точкой меняется на запятую.

Задание. Замените операцию на (x в степени y). Напишите соответствующий обработчик события и обеспечьте его обработкой возможных ИС.

 

Указания. 1) xy = exp(y*ln(x))

2) Данная операция двуместная, поэтому ее нужно обрабатывать в процедуре SpeedButton18Click кнопки .

3) Возможные ИС: переполнение, неправильная операция ln.

 

Результаты работы

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-06-03 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: