Локальная обработка исключений.

I. Виды ошибок

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

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

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

II. Синтаксические ошибки

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

III. Логические ошибки

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

За наиболее часто встречающимися ошибками может следить сама программа. Для этого в настройках проекта (Project/ Options) – на вкладке Compiler надо выполнить следующие действия.

· На панели Code generation (Генерация машинного кода) сбросить флажок Optimization (Оптимизация). Когда компилятор создает оптимизированный код, он нередко вносит существенные улучшения в детали алгоритма, реализованного на Паскале. Например, могут не использоваться промежуточные переменные, в таком случае программист в процессе отладки не сумеет узнать значение этой переменной.

· На панели Runtime errors (Ошибки времени выполнения) должны быть установлены флажки Range Checking (Контроль выхода индекса за границы массива), I/O Checking (Контроль ошибок вода/вывода) и Overflow checking (Контроль переполнения при целочисленных операциях).

· На панели Debugging (Отладка) установить флажки Debug information (Добавление отладочной информации), Local symbols (Просмотр значений локальных переменных), Reference info (Просмотр структуры кода), Assertions (Включение процедуры Assert в машинный код) и Use Debug DCUs (Использование отладочных версий стандартных модулей библиотеки компонентов VCN). Процедура Assert выполняет отладочные функции. Отладочные версии стандартных модулей содержат дополнительные режимы проверки корректности работы с компонентами Delphi.

За более сложными ошибками разработчик должен следить из среды Delphi самостоятельно.

Наряду с просмотром исходного текста, для поиска логических ошибок можно использовать и другие приемы. В том числе инструментарий, применявшийся и Турбо Паскале 6.0/7.0. Основными инструментами отладки являются точки контрольного останова и окно наблюдения за переменными.

Точка останова задается с помощью опции View/Debug windows/ Breakpoints. Окно наблюдения за переменными вызывается опцией View/Debug Windows/Watches. Если программа запущена из среды Delphi, ее работу можно прервать в любой момент опцией Run/Program pause, или щелчком по соответствующей кнопке панели инструментов.

После контрольного останова в окне наблюдения отображаются текущие значения наблюдаемых объектов. Текущее значение любой переменной, также можно увидеть , если в окне редактора указать на нее мышью (окно редактора должно быть активным). Изменить текущее значение переменной можно с помощью окна Evaluate/Modify. Прервать выполнение приложения можно с помощью команды Run/Program reset (Выполнение/Прервать выполнение).

При использовании контрольных точек и окна наблюдения за переменными программист может прослеживать работу программы в пошаговом режиме с помощью клавиш F7 (Run/Trace Into) и F8 (Run/Step Over) (также можно применять команды Run/Trace to Next Source Line и Run/Run to Cursor).

IV.  Обработка исключений

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

В Delphi для обработки динамических ошибок в выполняемый файл приложения встраиваются специальные фрагменты кода, предназначенные для реагирования на исключительные ситуации. Базовым классом для всех исключений является класс Exception (Исключение).

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

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

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

Отметим свойства и методы объектов класса исключений. Свойство Message типа String содержит описание исключительной ситуации. Часто при возбуждении исключения этот текст появляется в диалоговом окне глобального обработчика исключительных ситуаций. Свойство HelpContext хранит номер идентификатора контекстной помощи для объекта исключения. Если номер идентификатора отличен от нуля, то при вызове контекстной помощи отображается соответствующий раздел справки. Если значение идентификатора равно нулю (по умолчанию), то отображается раздел справки родительского класса этого объекта.

Класс Exception имеет большое количество потомков, каждый из которых предназначен для конкретной ошибки. Отметим наиболее часто используемые

· EAbort – “тихое” исключение, используемое для прерывания текущего блока кода без вызова глобального обработчика.

· EOutOfMemory – не достаточно оперативной памяти для выполнения операции.

· EIntOutError – ошибка ввода/вывода файла любого типа.

· EIntError – базовый класс для обработки ошибок, связанных с операциями над целыми числами. Специализированные исключения обрабатываются потомками этого класса:

- EIntOverflow – переполнение в операции с целочисленными переменными;

- EDivByZero – деление целого числа на ноль;

- ERangeError – присвоение целочисленной переменной значения, выходящего за пределы допустимого диапазона (может вызываться при попытке обращения к элементам массива по индексу, выходящему за границы).

· EMathError – базовый класс для обработки ошибок в операциях с плавающей точкой. Специализированные исключения обрабатываются потомками этого класса:

- EInvalidOp – ошибка при выполнении операции над числом с плавающей точкой;

- EZeroDivide – деление на ноль числа с плавающей точкой;

- EOverFlow – присвоение вещественной переменной значения, которое не помещается в определенной области памяти;

- EUnderFlow – потеря значимости при операции над числами с плавающей точкой, результат получает нулевое значение.

· EInvalidPointer – некорректная операция с указателем.

· EInvalidCast – неверное приведение типов с помощью оператора as.

· EConvertError – ошибка преобразования типов, возникающая, например, при преобразовании строковых данных в числовые с помощью функций StrToInt или StrToFloat.

· EFCreateError – ошибка создания файла.

· EFOpenError – ошибка открытия файла.

· EResNotFound – указанном файле отсутствует ресурс.

· EListError, EStringListError – ошибка в списках.

· EPrinter – ошибка печати.

· EMenuError – ошибка в меню приложения.

· EInvalidGraphicOperation – неправильная операция с графическим объектом.

 

Механизм глобальной обработки исключений реализуется через объект Application, который имеет любое приложение. Код, выполняющий создание и запуск объекта Application, можно увидеть в файле проекта (DPR). Одной из функций этого объекта является обеспечение приложения глобальным обработчиком исключительных ситуаций.

При получении от системы сообщения об исключительной ситуации объект Application генерирует событие OnException типа TExceptionEvent. Обработчик этого события и является глобальным обработчиком исключительных ситуаций. По умолчанию на это событие для любых динамических ошибок, не имеющих своего обработчика, реагирует метод HangleException приложения. В теле процедуры HangleException (Sender: TObject) вызывается метод ShowException приложения, который выводит на экран диалоговое окно с описанием возникшего исключения.

Программист может выполнить обработку исключений, создав свой глобальный обработчик – обработчик события OnException. С этой целью удобно использовать компонент ApplicationEvents.

Событие OnException имеет тип TexceptionEvent, который описан следующим образом:

Type TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;

Параметр E представляет объект исключительной ситуации. С его помощью можно получить доступ к свойствам объекта исключения, например, к свойству Message, содержащему описание возникшего исключения.

Procedure TForm1.ApplicationEvents1Exception (Sender: TObject; E: Exception);

Begin

       MessageDlg(E.Message, mtInformation, [mbOk], 0);

       // Место размещения операторов, выполняющих развитую обработку исключений

End;

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

Замечание (процедуры и функции, реализующие диалоги). Процедура ShoMessage, функции MessageDlg и MessageDlgPos отображают окно (панель) вывода сообщений; функции InputBox и InputQuery окно (панель) для ввода информации.

Функция ShowMessage (const Msg: String) отображает окно сообщения с кнопкой Ok. Строка Msg выводится как текст сообщения.

Функция MessageDlg (const Msg: String; AType: TMsgDlgType; AButtons: TMsgDlgButtons; HelpCtx: Longint): Word отображает окно сообщений в центре экрана. Она позволяет получить ответ пользователя. Параметр Msg содержит выводимое сообщение.

Окно сообщений может иметь различный тип и наряду с сообщением содержать иконки. Тип окна сообщения определяется параметром AType, который может принимать следующие значения:

· mtWarning – окно содержит черный восклицательный знак в желтом треугольнике и заголовок Warning;

· mtError – окно содержит белый крест в красном круге и заголовок Error;

· mtInformation – окно содержит букву i синего цвета в белом круге и заголовок Information;

· mtConfirmation – окно содержит знак ? синего цвета в белом круге и заголовок Confirmation (подтверждение);

· mtCustom – окно не содержит иконки, в заголовке выводится название исполняемого файла приложения.

Параметр AButtons задает набор кнопок окна и может принимать любые комбинации следующих значений, которые задают надпись на кнопке:

· mbYes

· mbNo

· mbOk

· mbCancel – Cancel (Отмена)

· mbHelp

· mbAbort

· mbRetry

· mbIgnore

· mbAll

Для параметра AButtons имеются две константы mbYesNoCancel и mbOkCancel, определяющие предопределенные наборы кнопок.

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

Параметр HelpCtx определяет контекст (тему) справки, появляющейся во время отображения диалога при нажатии пользователем клавиши F1. Обычно значение этого параметра равно нулю.

procedure TForm1.Button1Click(Sender: TObject);

 var Res: TModalResult;

begin

   If length (EditDate.Text)<8 then

     Begin

           res:=MessageDlg('Неправильная дата!'#10#13'Исправить автоматически?', mtError, [mbOk, mbNo], 0);

           If res=mrOk then editdate.Text:=DateToStr(Date);

           If res=mrNo then editdate.SetFocus;

     End;

end;

При нажатии клавиши Button1 производится простейшая проверка даты введенной в поле редактирования EditDate. Если длина кода даты меньше допустимой, выдается предупреждение и запрос на автоматическую коррекцию. При щелчке по кнопке Ok в поле редактирования записывается текущая дата, при отрицательном ответе фокус ввода передается полю редактирования.

Функция MessageDlgPos (const Msg: String; ATpe: TMsgDlgType; AButtons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Word отличается от функции MessageDlg наличием параметров X и Y, управляющих расположением диалогового окна на экране.

 

Локальная обработка исключений.

Для обеспечения возможности использования локальных (специализированных) обработчиков исключений в состав языка введены две конструкции try .. finally  и try .. except. Обе конструкции имеют похожий синтаксис, но различное назначение. Блоки try включают операторы программы, которые могут вызвать исключительную ситуацию.

Конструкция try .. finally состоит из двух секций и имеет следующий формат:

Try

       // Операторы, выполнение которых может вызвать ошибку

finally

       // Операторы, которые должны быть выполнены даже в случае ошибки

end;

Формат конструкции try .. except следующий:

Try

       // Операторы, выполнение которых может вызвать ошибку

except

       // Операторы, которые должны быть выполнены в случае ошибки

end;

В каждой из этих конструкций выполняются операторы секции try, если в результате возникает исключительная ситуация, то управление передается первому оператору секции finally или секции except. Если исключительная ситуация не возникла, то в случае конструкции try .. finally последовательно выполняются все операторы обеих секций, в случае использования конструкции try .. except операторы секции except не выполняются.

procedure TForm1.Button1Click(Sender: TObject);

begin

try

    edit1.Text:=FloatToStr(2*StrToFloat(Edit1.Text));

except

If MessageDLg('Содержимое поля Edit1 равно '+Edit1.Text+#10#13+'Это не число!',mtError,[mbOk],0)=mrOk Then

           begin

                   Edit1.text:='';

                   Edit1.SetFocus;

           end;

end;

end;

Секция except может быть разбита на несколько частей конструкциями on .. do, позволяющими анализировать класс исключительной ситуации с целью ее обработки. Конструкция on .. do применяется в случаях, когда действия зависят от класса исключения:

On <Идентификатор: класс исключения> do

       <оператор обработки исключения этого класса>;

else

       <оператор >;

procedure TForm1.Button1Click(Sender: TObject);

begin

try

    label1.Caption:=FloatToStr(StrToFloat(Edit1.Text)/FloatToStr);

except

 On EConvertError do

If MessageDLg('Содержимое поля Edit1 равно '+Edit1.Text+#10#13+'Это не число!',mtError,[mbOk],0)=mrOk Then

           begin

                   Edit1.text:='';

                   Edit2.Text:='';

                   Edit1.SetFocus;

           end;

On EZeroDivide do

If MessageDLg('Делить на ноль нельзя',mtError,[mbOk],0)=mrOk Then

           begin

                   Edit2.text:='';

                   Edit2.SetFocus;

           end;

end;

end;

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

Конструкции try могут быть вложенными и размещаться одна в другой.

При необходимости исключительную ситуацию можно вызвать программно.

 


Дата добавления: 2021-01-20; просмотров: 58; Мы поможем в написании вашей работы!

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




Мы поможем в написании ваших работ!