Программа на рис. 14.7 всегда будет чистить за собой экран и заканчивать свою работу выдачей одного из предписанных сообщений. Если выполнимый код программы создан в режимах $R- и $I-, то варианты 2..199 и 201 могут никогда не сработать. Можно было использовать условную компиляцию для изъятия их из текста при необходимости.
В принципе возможно создать целую цепочку процедур завершения. Для этого надо лишь в каждой процедуре присваивать
- 310 -
| USES CRT; { используется модуль CRT }
| VAR
| OldExitProc : Pointer; { здесь запомнится ExitProc }
| {$F+} { режим компиляции $F+ }
| PROCEDURE NewExit; { новая процедура выхода }
| BEGIN
| ExitProc := OldExitProc; { восстановление пути выхода }
| TextAttr := White; { задание белого цвета (CRT) }
| ClrScr; { очистка всего экрана (CRT) }
| if ErrorAddr <> nil { Выход из-за ошибки? }
| then { Да. Обрабатывается ее код. }
| case ExitCode of
| 2..199:WriteLn('Ошибка ввода-вывода.' );
| 200 :WriteLn('ДЕЛЕНИЕ НА 0.Проверьте входные данные');
| 201 :WriteLn('Переполнение диапазона.' );
| 203 :begin
| WriteLn('HE ХВАТАЕТ СВОбОДНОЙ ПАМЯТИ.' );
| WriteLn('Освободите память и повторите запуск');
| end;
| 205 :WriteLn('Переполнение в вещественном числе.');
| 206 :WriteLn('Потеря порядка в вещественном числе.' );
| else WriteLn ('Ошибка ', ExitCode, '. ',
| 'Смотрите описание TURBO PASCAL 5.5')
| end {case и then}
| else (Нет. Нормальное завершение }
| case ExitCode of
| 255 :WriteLn('Программа прервана.');
| else WriteLn('Код завершения программы : ', ExitCode )
| end; {case и else}
| ErrorAddr := nil; { обнуление адреса ошибки }
| END; {$F-} { можно вернуть режим $F- }
| { == ОСНОВНОЙ БЛОК ПРОГРАММЫ == }
| BEGIN
| OldExitProc:= ExitProc; {запоминается адрес ExitProc }
| ExitProc:= @NewExit; {назначается новая процедура }
| {...любые остальные действия программы... }
| END.
Рис. 14.7
переменной ExitProc адрес следующей процедуры, написанной по тем же правилам, и лишь в самой последней из них восстановить исходное значение ExitProc.
- 311 -
Иногда удобно оформлять процедуры завершения как модули. Программу на рис. 14.7 очень легко переделать в модуль. Надо лишь вписать слова unit Имя, interface и implementation. Тогда при его подключении к основной программе инициализирующая часть настроит процедуру завершения еще до начала выполнения основной программы. Подключать такой модуль надо будет одним из первых в списке раздела USES.
14.8.1. Оператор RunError
В Турбо Паскале введен особый оператор
RunError(N : Word)
Его предназначение — останавливать работу программ так, как будто произошла фатальная ошибка с номером N. Всюду, где можно поставить оператор Halt, можно поставить и оператор RunError. Отличие будет лишь в том, что в последнем случае программа завершится выдачей сообщения об ошибке. Оператор RunError очень удобен при отладке программ, особенно содержащих процедуры завершения и обработки ошибок. С его помощью можно испытать программу на рис. 14.7, не провоцирую реальных критических ситуаций. Вызов RunError без указания номера ошибки эквивалентен вызову RunError(0).
14.8.2. Сводка номеров фатальных ошибок
Фатальные ошибки (табл. 14.2) всегда приводят к немедленной установке программы.
Таблица 14.2