Исключительные ситуации

Исключительная ситуация (exception) — это прерывание нормального хода работы программы из-за невозможности правильно выполнить последующие действия. Для обработки исключений в Delphiпредусмотрен механизм защищенного блока. Защищенный блок начинается зарезервированным словом try(попытаться) и завершается словом end. Внутри блока располагается часть программы, в которой может возникнуть исключительная ситуация (ошибка). Существует два вида защищенных блоков: первый - в случае возникновения ошибок выполняются предусмотренные программистом действия и второй блок – независимо от того, была ошибка или нет, выполнить те или иные действия.

Первый блок завершается зарезервированым словом except (исключить), после которого следуют операторы обработки исключительной ситуации:

try

// защищаемые от ошибок операторы

except

// операторы обработки исключительной ситуации

end;

Между словами try и except помещаются защищаемые от ошибок операторы. Если при выполнении любого из этих операторов возникает исключительная ситуация, то управление передается операторам между словами exceptи end, образующими блок обработки исключительных ситуаций. При нормальном (безошибочном) выполнении программы блок except...end пропускается. При написании программы можно использовать вложенные защищенные блоки, чтобы организовать локальную и глобальную обработку исключительных ситуаций.

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

try

{ вычисления с вещественными числами }

except

on EZeroDivide do {обработка ошибки деления на нуль};

on EMathError do {обработка других ошибок

вещественной математики }

else {обработка всех остальных ошибок (обработчик по

умолчанию };

end;

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

Второй блок завершается зарезервированным словом finally (окончательно). Этот блок используется в том случае, когда программа распределяет некоторый ресурс (например, связывает файловую переменную с ресурсом на диске), но исключительная ситуация прерывает ее действие, а связь остается. Блок записывается следующим образом:

// запрос ресурса

try

// защищаемые операторы, которые используют ресурс

finally

// освобождение ресурса

end;

Если программа использует сразу несколько ресурсов, то блок try.. finally.. end может быть вложенным столько раз, сколько потребуется.

В таблице 9 представлены часто используемые в данном курсе классы исключительных ситуаций:

Таблица 9

Класс исключительных ситуаций Описание
EInOutError Ошибка доступа к файлу или устройству ввода-вывода.
EIntError Общий класс исключительных ситуаций целочисленной арифметики, от которого порождены классы EDivByZero, ERangeError и EIntOverflow.
EDivByZero Попытка деления целого числа на нуль.
ERangeError Выход за границы диапазона целого числа или результата целочисленного выражения.
EIntOverflow Переполнение в результате целочисленной операции.
EMathError Общий класс исключительных ситуаций вещественной математики, от которого порождены классы EInvalidOp, EZeroDivide, EOverflow и EUnderflow.
EZeroDivide Попытка деления вещественного числа на нуль.
EOverflow Потеря старших разрядов вещественного числа в результате переполнения разрядной сетки.
EUnderflow Потеря младших разрядов вещественного числа в результате переполнения разрядной сетки.
EConvertError Ошибка преобразования данных с помощью функций IntToStr, StrToInt, StrToFloat, StrToDateTime.

 

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

Пример 17. Программа деления двумерного массива на число.

Положите на форму компоненты, как показано на рисунке 34.

 

Рисунок 34 - Внешний вид приложения на этапе конструирования

 

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

 

Текст программы:

const

Nmax=255;

Mmax=255;

var

n,m:integer;

A,B:array [1..Nmax,1..Mmax] of real;

 

procedure TForm1.LabeledEdit1KeyPress(Sender: TObject; var Key: Char);

begin

if not (key in ['0'..'9',#8,'-',

DecimalSeparator]) then key:=#0;

end;

 

procedure TForm1.BitBtn1Click(Sender: TObject); //Ввод m,n

begin

try // пользователь может ввести не целое число

n:=StrToInt(Form1.LabeledEdit1.Text);

m:=StrToInt(Form1.LabeledEdit2.Text);

Except

begin

MessageDlg('Ошибка ввода размерности!',

mtError,[mbOK],0);

exit;

end;

End;

if (n<=0) or (m<=0) then

begin

MessageDlg('неправильно введена размерность

массива!',mtError,[mbOK],0);

exit;

end;

Form1.StringGrid1.RowCount:=m;

Form1.StringGrid1.ColCount:=n;

Form1.StringGrid1.Width:=

Form1.StringGrid1.DefaultColWidth*n+10;

Form1.StringGrid1.Height:=

Form1.StringGrid1.DefaultRowHeight*m+10;

Form1.StringGrid1.Show;

Form1.BitBtn2.Show;

Form1.Label2.Caption:='Заполните массив';

Form1.Label2.Show;

end;

 

procedure TForm1.FormShow(Sender: TObject);

// метод «Показ формы» - установка начальных значений

begin

//эти методы и свойства можно установить в Инспекторе объектов

{реакция нажатия на клавишу для всех следующих компонентов одинакова:можно вводить только вещественные числа}

Form1.LabeledEdit2.OnKeyPress:=

Form1.LabeledEdit1.OnKeyPress;

Form1.LabeledEdit3.OnKeyPress:=

Form1.LabeledEdit1.OnKeyPress;

Form1.StringGrid1.OnKeyPress:=

Form1.LabeledEdit1.OnKeyPress;

{для первой сетки разрешен ввод значений с клавиатуры. Т.к. свойство Options является множеством, то следует перечислить все поля данного свойства, которые равны True}

Form1.StringGrid1.Options:=

[goFixedVertline,goFixedHorzLine,

goVertLine,goHorzLine,goEditing];

Form1.StringGrid1.FixedCols:=0;

Form1.StringGrid1.FixedRows:=0;

Form1.StringGrid1.Hide;

Form1.StringGrid2.FixedCols:=0;

Form1.StringGrid2.FixedRows:=0;

//---------------------

Form1.StringGrid2.Hide;

Form1.Label1.Hide;

Form1.Label2.Hide;

Form1.LabeledEdit3.Hide;

Form1.BitBtn2.Hide;

Form1.BitBtn4.Hide;

end;

 

procedure TForm1.BitBtn2Click(Sender: TObject);//Ввод массива

var

i,j:integer;

begin

Try

for i:=0 to n-1 do

for j:=0 to m-1 do

A[i+1,J+1]:=

FloatToStr (Form1.StringGrid1.Cells[i,j]);

Except

on EConvertError do

begin

MessageDlg('Ошибка! Это не число', mtError,

[mbOK],0);

exit;

end;

End;

Form1.BitBtn4.Show;

Form1.LabeledEdit3.Show;

end;

 

procedure Dividion;

//Процедура деления. Написана самим программистом

var

k,i,j:integer;

begin

Form1.StringGrid2.RowCount:=m;

Form1.StringGrid2.ColCount:=n;

Form1.StringGrid2.Width:=

Form1.StringGrid2.DefaultColWidth*n+10;

Form1.StringGrid2.Height:=

Form1.StringGrid2.DefaultRowHeight*m+10;

Try

k:=StrToInt(Form1.LabeledEdit3.Text);

for i:=1 to n do

for j:=1 to m do

begin

B[i,j]:=A[i,j] / k;

Form1.StringGrid2.Cells[i-1,j-1]:=

FloatToStr (B[i,j]);

end;

Except

on EConvertError do

begin

MessageDlg(' Ошибка! Это не число',

mtError,[mbOK],0);

exit;

end;

on EZeroDivide do

begin

MessageDlg('Деление на нуль!',

mtError,[mbOK],0);

exit;

end;

end;//try

Form1.StringGrid2.Show;

Form1.Label1.Show;

Form1.LabeledEdit3.EditLabel.Caption:=

'Введенное число';

end;

 

procedure TForm1.BitBtn4Click(Sender: TObject);

begin

Form1.Label2.Caption:='Введенный массив';

Dividion;

end;

 

 

Пример 18. Расчет факториала. В данном примере использован целый тип данных результата вычисления.

Для того, чтобы включить проверку на переполнение, следует выбрать в главном меню Delphi пункт Project/Options. Откроется окно, в котором нужно выбрать вкладку Compilerи установить флаги проверок ошибок во время выполнения приложения (Runtime errors). Окно представлено на рисунке 35.

.

Рисунок 35 - Установка проверки ошибок

 

Текст программы:

var

f:integer;

function fact (n:integer):Integer;

begin

if n=1 then Result:=1

else

Result:=Fact(n-1)*n;

end;

 

procedure TForm1.BitBtn1Click(Sender: TObject);

begin

Try

f:=StrToInt(Form1.Edit1.Text);

Form1.Edit1.Text:=IntToStr(fact(f));

Except

on EConvertError do MessageDlg('Неправильно

введено число!',mtError,[mbOK],0);

on EIntOverFlow do MessageDlg

('Переполнение!',mtError,[mbOK],0);

End;

end;

 

Пример 19. Процедура записи в файл. При нажатии на кнопку происходит расчет функции с заданным шагом и в заданном диапазоне. Результаты расчета записываются в файл.

 

procedure TForm1.BitBtn1Click(Sender: TObject);

var

f:TextFile;

begin

Try

{файл с расчетами называется Test.txt и будет лежать в том же месте, что и исполняемый файл данного приложения (имя у этого приложениям Project1),у вас может быть другое имя}

AssignFile(f,ExtractFilePath('Project1.exe')

+'Test.txt');

ReWrite(f);

x:=x0;

repeat

y:=a*X*X+b*X+c;

WriteLn(f,FloatToStr(x)+' '+FloatToStr(y));

x:=x+h

until x>xk;








Дата добавления: 2015-04-10; просмотров: 1007;


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

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.045 сек.