18.9 Некоторые приемы программирования, встраивающие отладку в код
Тем, кто пока слабо владеет программированием и не знает языка Object Pascal,
изложенный в данном разделе материал сначала стоит просто просмотреть «по
диагонали», чтобы уловить главное. А после более тесного знакомства с Object
Pascal, я бы рекомендовал вернуться к этому материалу и познакомиться с ним
более осмысленно.
В Object Pascal в Delphi введен полезный инструмент для отладки — процедура
Assert. Она объявлена следующим образом:
Процедура применяется при отладке программ для проверки истинности утверждений,
которые по замыслу должны быть истинны, но в силу каких-то ошибок могут
нарушаться. Если проверяемое утверждение окажется ложным, процедура приводит к
прекращению работы, генерации исключения EAssertionFailed и выдаче
сообщения об ошибке.
Процедура Assert получает в качестве первого параметра булево выражение expr,
которое и проверяется на истинность. В процедуру может быть также передана
строка сообщения msg. Если проверяемое утверждение оказывается ложным, то
генерируются исключения EAssertionFailed с заданной строкой сообщения. Если
строка в вызове процедуры Assert не указана, то исключение генерируется со
стандартной строкой сообщения. Сообщение отображается с указанием имени файла,
полным путем к файлу и номером строки, в которой находится вызов Assert,
соответствующий ложному выражению.
Если исключение EAssertionFailed не будет перехвачено, оно вызовет прерывание
работы программы с кодом 227.
Попробуйте использовать эту процедуру в вашем тестовом приложении. Измените,
например, цикл в этом приложении на следующий:
for i:=1 to 5 do begin
A := A * A;
Assert(A<=1e250,'A = '+FloatToStr(A) + ', i='+IntToStr (i));
end;
В этом коде проверяется условие А <=10^250, и если оно нарушается, то выдаетcz
текст сообщения об ошибке. Если вы запустите свое приложение, то при повторном
щелчке на кнопке получите сначала длинное сообщение, после которого выполнение
прервется. Это сообщение и прерывание можно убрать. Для этого надо выполнить
команду Tools | Debugger Options и в открывшемся окне на странице Language
Exception снять флажок индикатора Stop on Delphi Exception.
Если после прерывания вы нажмете F9, чтобы продолжать выполнение приложения, то
увидите сообщение, которое и было предусмотрено вами в процедуре Assert. Кроме
заказанного вами текста в сообщении указывается модуль и строка, в которой
произошло событие.
Закономерен вопрос: «А зачем нужна специальная процедура Assert, если то же
самое можно было бы сделать простым оператором if?». Действительно, оператор
if (A>1e250) then
ShowMessage('А = '+FloatToStr(A) + ', i='+IntToStr(i) ) ;
выдал бы примерно такое же сообщение. Особенностью и преимуществом процедуры
Assert является то, что она работает только при включенной директиве проверки
утверждений {$С+} или {$ASSERTIONS ON}. Они включены по умолчанию. А поскольку в
отлаженной программе процедура Assert обычно работать не должна, то перед
окончательным оформлением выполняемого модуля можно скомпилировать файл с
директивой {$С-} или {$ASSERTIONS OFF). При этом компиляция проверок не будет
производиться, так что в отлаженной программе не остается ничего лишнего. Это вы
можете проверить сами, включив в модуль директиву компилятора {$С-}.
Однако возможности процедуры Assert достаточно скромны. Поэтому часто полезно
включать в приложение отладочную печать, которая помогает следить за ходом
процесса. В Delphi для этого, на мой взгляд, удобен компонент Memo -
многострочное окно редактирования. В него можно заносить отладочные данные и тут
же, во время выполнения приложения просматривать их. Чтобы этот компонент не
занимал место на форме, его можно выводить в отдельное окно. Приведу без особых
комментариев, как это можно было бы сделать в нашем тестовом примере, если бы
нам вдруг для отладки захотелось наблюдать, как изменяются в цикле переменные.
implementation
{$R *.DFM}
var FDebug:TForm; // форма отладочного окна
Memo1:TMemo; // Компонент вывода в отладочном окне
A:double;
LDebug:Word=0; // уровень отладки
procedure TForm1.Button1Click(Sender: TObject);
var i: word;
begin
for i:=1 to 5 do begin // отладочная печать при уровне - 1
if LDebug=1 then
Memo1.Lines.Add('A = ' + FloatToStr(A) + ', i=' + IntToStr(i));
A := A * A;
End;
Edit1.Text := FloatToStr(A);
procedure TForm1.FormCreate(Sender: TObject);
begin
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow,
exUnderflow, exPrecision]); //установка уровня отладки; можно закомментировать
LDebug := 1;
if LDebug > 0 then begin
FDebug := TForm.Create(Self);
FDebug.Caption :=, 'Отладка';
Memo1 := TMemo.Create(FDebug);
Memo1.Parent := FDebug;
Memo1.ScrollBars := ssVertical;
Memo1.Align := alClient;
FDebug.Show;
End;
End;
procedure TForm1.FormDestroy(Sender: TObject);
begin
It LDebug > 0 then FDebug.Release;
End;
В этом коде прокомментировано все, относящееся к отладке. В обработчике события
формы OnCreate задается уровень отладки оператором
LDebug := 1;
Уровень может определять степень подробности вывода отладочной информации. Если
отладка вообще не нужна, этот оператор можно закомментировать.
При уровне отладки LDebug > 0 создается окно отладки и в нем — компонент Memo1,
в который и выводится отладочная информация. В данном примере вывод этой
информации вставлен в цикл.
В событии формы OnDestroy предусмотрено уничтожение отладочного окна. Попробуйте
сделать в приложении указанные изменения и запустить его на выполнение. Вы
увидите в процессе выполнения окно, в которое по мере работы приложения будут
заноситься данные. Если бы это было какое-то сложное приложение, то вы
непосредственно в процессе выполнения могли бы просматривать эти данные и
наблюдать за ходом работы.
Сайт
рассылки http://mydelphi7.narod.ru,
на котором есть архив рассылки, также гостевая книга, переводчик.
Копировать, размещать, продавать представленную информацию
запрещается.