Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочник Pascal ABC.doc
Скачиваний:
66
Добавлен:
07.11.2018
Размер:
985.6 Кб
Скачать

Оператор raise

Оператор raise предназначен для возбуждения исключения и имеет вид:

raise объект

Здесь объект - объект класса, производного от Exception. Например:

raise Exception.Create('Ошибка');

При возбуждении специфического исключения желательно определить свой тип исключения

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

function ctg(x: real): real; begin   Result:=cos(x)/sin(x); end;

Если вызвать ctg(0), то будет возбуждено исключение EZeroDivide вещественного деления на 0.

Рассмотрим наивную попытку обработать ошибочную ситуацию внутри функции ctg:

function ctg(x: real): real; begin   if x=0 then     writeln('Функция ctg: деление на 0');   Result:=cos(x)/sin(x); end;

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

Простейший способ - оставить исходный вариант функции и обрабатывать исключение EZeroDivide:

try   readln(x);   writeln(ctg(x)/(x-1));   ... except   on EZeroDivide do     writeln('Деление на 0');  end;

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

Однако, последнее решение обладает существенным недостатком: исключение EZeroDivide будет возбуждено и при x=1 и не будет связано с функцией ctg. Для устранения подобного недостатка определим собственный класс исключения и возбудим его в функции ctg:

type ECtgError=class(Exception) end;  

function ctg(x: real): real; begin   if x=0 then     raise ECtgError.Create('Функция ctg: деление на 0');   Result:=cos(x)/sin(x); end;

Тогда обработка ошибок будет выглядеть так:

try   readln(x);   writeln(ctg(x)/(x-1));   ... except   on EZeroDivide do     writeln('Деление на 0');    on e: ECtgError do     writeln(e.Message);  end;

Если сделать ECtgError наследником класса EMathError, как и EZeroDivide, то последний код можно упростить:  

type ECtgError=class(EMathError) end;

...

try   readln(x);   writeln(ctg(x)/(x-1));   ... except   on e: EMathError do     writeln(e.Message);  end;

Заметим, что если в блоке try произойдут другие исключения, то они не будут обработаны.

Наконец, исправим еще одну неточность. Исключение ECtgError должно генерироваться не только когда аргумент x равен 0, но и когда он кратен Pi. Чтобы не проверять это сложное условие, поступим следующим образом: перехватим в функции ctg исключение EZeroDivide и в ответ сгенерируем новое - ECtgError:

function ctg(x: real): real; begin   try     Result:=cos(x)/sin(x);   except     on e: EZeroDivide do       raise ECtgError.Create('Функция ctg: деление на 0');   end; end;