ЖИЗНЕННЫЙ ЦИКЛ ПРОГРАММ. ОТЛАДКА

Машинная программа выполняет то, что
Вы ей приказали делать, а не то, что
Вы бы хотели, чтобы она делала
«Закон Мерфи». Артур Блох

Данная работа является продолжением статьи, напечатанной в преды-
дущем номере и посвященной вопросам тестирования программ.
Выясним, как поступить, если тестирование показало, что в програ-
мме есть ошибки. В этом случае необходимо выполнить отладку программы.
О т л а д к а — это этап исправления ошибок в программе. По ут-
верждению Майерса /2/ на отладку программы требуется порядка 70% вре-
мени от всей работы над программой.
В процессе отладки Вам придется преодолеть естественные затрудне-
ния, которыми обычно сопровождаются любые интеллектуальные усилия. Не-
обходимо будет перепробовать множество различных методов, — и «под-
держкой для Вас будет только твердая уверенность, что правильное реше-
ние действительно существует».
Отладка программ обычно осуществляется посредством тестов и отла-
дочной печати (или расстановкой точек прерывания). Когда мы тестируем
программу, мы проверяем, совпадают ли ожидаемые результаты с выданными
программой. Но иногда в результате того, что несколько ошибок «гасят»
друг друга, мы получаем, что неправильная программа выдает на несколь-
ких тестах правильный ответ, поэтому необходимо еще проверять и проме-
жуточные результаты счета. С этой целью используется отладочная печать
(или выставляются точки прерывания).
Отладочная печать позволяет отследить и проанализировать, как
программа преобразовывает данные, и насколько эти преобразования сов-
падают с теми, которые мы от программы ожидаем.
Самый простой метод — это поставить отладочную печать после кажд-
ого оператора. Но получающийся при этом объем информации будет черес-
чур большим и мы просто не сможем ее всю проанализировать. Поэтому мы
пойдем другим путем. Возьмем блок-схему программы (или представим себе
структуру программы) и попытаемся разбить ее на несколько частей та-
ких, что каждый блок выполняет какую-то законченную часть работы. Меж-
ду этими частями и имеет смысл ставить отладочную печать.
При этом обычно отладочная печать не ставится во внутренних цик-
лах (причина, наверное, ясна). Если все же возникла такая необходи-
мость, то можно распечатывать значения переменных не при каждом выпол-

— 2 —
нении цикла, а, например, один раз из пяти.
Также имеет смысл проанализировать, какие блоки программы были
выполнены. С этой целью в начале больших ветвей имеет смысл поставить
печать сообщения о том, что управление передано на указанную ветвь.
В случае, если мы впервые обнаружили расхождение с ожидаемыми ре-
зультатами после, например, пятого блока, то именно в этом блоке, судя
по всему, и есть ошибка.
При проверке программы человека иногда «зацикливает», например,
он начинает считать, что между буквами «а» и «б» в алфавите пропущена
какая-то буква, или что 2+2=5, и поэтому результаты, выдаваемые прог-
раммой, кажутся ему абсолютно верными. Поэтому при финальной проверке
программы желательно решить задачу другим способом (а не описанным в
программе) и проверить совпадение полученных результатов (на стадии
отлавливания семантических ошибок этот подход ничего не дает, так как
мы не можем оценить правильность промежуточных данных).
Для отладки линейных участков программ поступают следующим обра-
зом. Пусть на некотором линейном участке программы происходят вычисле-
ния по какой-то, быть может, достаточно сложной формуле. Причем в ходе
решения задачи обращение к этому участку происходит многократно и для
различных значений аргументов формулы. Чтобы проверить правильность
этого участка программы, задают для этой формулы некоторый определен-
ный набор аргументов, называемый тестовым. Просчитывают вручную (можно
воспользоваться и микрокалькулятором) формулу с этими значениями аргу-
ментов. А затем выполняют на ЭВМ тот участок программы, который произ-
водит вычисления по этой формуле с теми же аргументами. Если результа-
ты ручного счета и машинного не совпадают, то надо искать ошибку.
Ошибка может быть как в том так и в другом способах решения. Поэтому
надо проверять и результаты ручного счета.
Кстати, если для ЭВМ неважно, какие числа взяты в качестве аргу-
ментов, то для ручного счета это, конечно, совсем не безразлично. Час-
то удобно, например, брать целые числа — 0, 1, 2 и т.д. При этом надо
следить за тем, чтобы выбранные значения аргументов не помешали выя-
вить возможные ошибки. Например, если вычисления вести по формуле

то, задав значение a, равное или очень близкое к 2, мы не заметим воз-
можных ошибок при вычислении значения выражения

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

— 3 —
результаты с полученными вручную, мы увидели бы, где они не совпадают,
и тем самым локализовали бы ошибку, нашли ее, а затем исправили.
Дадим практические рекомендации по отладке программ в среде Тур-
бо-Паскаль. Язык Паскаль предоставляет пользователю мощную интегриро-
ванную среду с автоматическим управлением программного проекта, мо-
дульной организацией программ, высокой скоростью компиляции. Однако
эти средства не избавляют программу от ошибок, которые приводят к неп-
равильной ее работе.
В помощь пользователю Паскаль предоставляет средства, необходимые
для отладки программы, которые позволяют тщательно протестировать
программу и устранить все ошибки в ней.
Турбо Паскаль дает возможность пользователю легко определять мес-
тоположение ошибок при компиляции и выполнении программы, включить или
выключить автоматический контроль ошибок при выполнении программы.
Кроме того Паскаль содержит мощный и гибкий отладчик, который позволя-
ет выполнить программу построчно, просматривать и модифицировать пере-
менные и выражения. Отладчик встроен в интегрированную среду и поэтому
пользователь может редактировать, компилировать и отлаживать программу
не выходя из Турбо Паскаля.
Существует три основных типа ошибок: ошибки компиляции, ошибки
выполнения и логические ошибки.
1. Ошибки компиляции. Ошибки компиляции, или синтаксические ошиб-
ки, возникают в том случае, если не описана некоторая переменная, пе-
редается неправильное количество параметров процедуре или функции,
присваивается вещественное значение целочисленной переменной и т.д. С
исправлением ошибок, обнаруженных во время компиляции, сложностей,
обычно, не возникает. Компилятор, обнаружив в программе ошибку, завер-
шает работу и передает управление и информацию об ошибке встроенному
редактору текстов. В результате такого взаимодействия в окне редакти-
рования появляется фрагмент программы, содержащий ошибку, а курсор
указывает конкретное место в программе, приведшее к возникновению
ошибки. Исправив таким образом обнаруженную ошибку, можно повторить
компиляцию программы.
2. Ошибки выполнения. Ошибки выполнения, или семантические ошиб-
ки, возникают на этапе выполнения при попытке открыть несуществующий
файл, делить на нуль и т.д. При этом выполнение программы прерывается
и на экран выдается сообщение об ошибке с указанием адреса ее возник-
новения в виде
Runtime error nnn at xxx:yyy, где nnn — номер ошибки времени вы-
полнения, xxx:yyy — адрес ошибки времени выполнения (сегмент и смеще-
ние). Ошибки времени выполнения делятся на две категории: ошибки вво-
да-вывода (коды ошибок с 1 до 199) и фатальные ошибки (коды ошибок с

— 4 —
200 до 255).
Ошибки ввода-вывода вызывают завершение выполнения программы в
случае, если конкретный оператор был скомпилирован в режиме {$I+}. В
режиме {$I-} программа продолжает выполнение, а ошибка описывается
функцией IOResult.
Возникновение фатальных ошибок приводит к немедленному прекраще-
нию выполнения программы.
3. Логические ошибки.
Программа может содержать и логические ошибки. Наличие таких оши-
бок определяется с помощью тестирования. Обнаружить ошибку этой груп-
пы, не имея никаких отладочных средств, бывает достаточно сложно. На-
личие в программе таких ошибок является одной из основных причин воз-
никновения необходимости использования отладчика, входящего в состав
интегрированной среды Турбо Паскаль.
Основные возможности отладчика. . Очень часто при поиске ошибки в
программе возникает необходимость выполнить программу в диалоговом ре-
жиме, наблюдая за изменением значений отдельных переменных или выраже-
ний, имея при этом возможность остановится в заданной точке программы
и изменить значения некоторых переменных и выражений. Такую среду для
отладки программ создает отладчик Турбо Паскаль.
Команды отладчика собраны в трех меню: Run, Break/watch, Debug.
Ниже более подробно описываются основные возможности, предоставляемые
отладчиком Турбо Паскаль.
Трассировка — это построчное выполнение исходной программы, при
котором после выполнения каждой строки можно остановится и посмотреть
результаты. Если в программе вызывается процедура или функция, предос-
тавляется выполнить этот вызов как один шаг трассировки, либо войти в
вызываемую подпрограмму и протрассировать ее построчно.
Выполнение до курсора — выполнение исходной программы до строки,
на которую указывает курсор. Наличие такой возможности позволяет про-
пустить трассировку малоинтересных частей программы и сразу перейти в
точку начала отладки.
Прерывание выполнения программы . Некоторые строки программы могут
быть помечены как точки прерывания. Когда в процессе выполнения прог-
раммы достигается точка прерывания, выполнение программы приостанавли-
вается и на экране отображается фрагмент исходного текста программы,
содержащий точку прерывания. Остановившись в точке прерывания можно
просмотреть значения переменных, начать трассировку или выполнить
программу до следующей точки прерывания. Кроме того существует возмож-
ность прервать выполнение программы в любой точке, нажав CTRL-PAUSE.
Это приводит к остановке на следующей выполняемой строке исходного ко-
да (как будто там находится точка прерывания).

— 5 —
Наблюдение. Отладчик интегрированной среды Турбо Паскаль предос-
тавляет возможность наблюдения за изменением некоторых (выбранных
программистом) переменных или выражений. Наблюдаемые объекты помещают-
ся в окно наблюдения (WATCH), отражая изменения в программе при поша-
говом выполнении.
Вычисление. Отладчик предоставляет возможность проверки и модифи-
кации значений переменных, выражений, структур данных (команда меню
Bedug/Evaluate).
Отладочная среда. При работе в интегрированной среде
Турбо Паскаль на экране обычно отображается основное меню и два окна:
окно редактирования (Edit) и окно наблюдения (Watch) либо окно редак-
тирования (Edit) и окно вывода (Output). Имеется возможность отображе-
ния экрана программы пользователя, увеличения определенного окна до
полного размера, перехода от одного экрана к другому. Ниже приведен
полный перечень экранов, доступных программисту в процессе отладки
программы.
Экран пользователя. Экран пользователя исчезает при входе в ин-
тегрированную среду Турбо Паскаля. Отображается вновь при выполнении
программы. После завершения выполнения программы опять исчезает.
Окно редактирования. При отладке в этом окне отображается исход-
ный текст программы. В процессе отладки можно использовать без ограни-
чений все команды редактирования, команды работы с файлами.
Окно наблюдения. В этом окне отображаются значения переменных,
выражений, структур данных, выбранных в качестве объектов наблюдения.
В начале это окно пустое. По мере того, как в него будут добавляться
или из него будут удалятся объекты наблюдения окно будет расширяться
либо сужаться. Для перехода в окно наблюдения используется клавиша F6.
для работы в окне наблюдения можно использовать клавиши управления
курсором (для передвижения светового курсора), клавишу ввода (для ре-
дактирования текста, выделенного световым курсором), клавиши Insert и
Delete (для добавления и удаления объектов наблюдения).
Окно вывода. Окно вывода содержит копию экрана пользователя
(только в текстовом режиме). Интегрированная среда Турбо Паскаль пре-
доставляет возможность в любое время (и а процессе отладки тоже) пе-
реключиться на экран пользователя, выполнив команду основного меню
Run/User screen или нажав клавиши Alt-F5.
Переключение между экраном пользователя и экраном интегрированной
среды может происходить автоматически. При трассировке программы иног-
да будет происходить переключение на экран пользователя на время вы-
полнения строки исходного текста, а затем обратное переключение на эк-
ран интегрированной среды. Команда основного меню Debug/Display swap-
ping позволяет управлять этим переключением. С помощью этой команды

— 6 —
можно выбрать один из трех режимов переключения между экраном интегри-
рованной среды и экраном пользователя:
Smart (иногда) — нормальный режим работы. В этом режиме переклю-
чение на экран пользователя происходит тогда, когда выполняемая в про-
цессе трассировки строка осуществляет вывод на экран;
Always (всегда) — режим, при котором переключение на экран поль-
зователя происходит на каждом шаге трассировки;
None (никогда) — режим, при котором переключение экранов не про-
исходит. В таком режиме программы, выполняющие вывод на экран, в ка-
честве экрана пользователя используют экран интегрированной среды (в
той строке на которую указывает световой курсор).
Команды отладки . Все команды отладки, собранные в трех меню,
приведены ниже в таблице. Вместе с командами меню приведены также и
некоторые клавиши, связанные с ними.
Табл. Команды отладки.

МЕНЮ

КОМАНДА

ФУНКЦИЯ

КЛАВИША

Run

Run

Выполняет программу. Если не-

обходимо, сначала ее переком-

пилирует

CTRL-F9

Program

Reset

Завершает сеанс отладки, осво-

бождает распределенную память

закрывает файлы, готовит про-

грамму к новому сеансу отладки

CTRL-F2

Go to

cursor

Выполняет программу до строки,

на которой установлен курсор

F4

Trase into

Выполняет строку программы. При

наличии вызова подпрограммы в

этой строке переходит к трас-

сировке подпрограммы

F7

Step over

Выполняет строку программы. При

наличии вызова подпрограммы в

этой строке перехода к трасси-

ровке подпрограммы не происходит

F8

User

screen

Выполняет переключение с экрана

интегрированной среды на экран

пользователя

ALT-F5

Debug

Evaluate

Отображает на экране окно для

CTRL-F4

МЕНЮ

КОМАНДА

ФУНКЦИЯ

КЛАВИША

вычислений позволяющее прос-

мотреть и если необходимо

скорректировать значения пере-

менных и выражений

Call stack

Отображает содержимое стека

вызовов. Позволяет осуществлять

обратную трассировку вызовов

программ

CTRL-F3

Find

procedure

Осуществляет поиск указанной

подпрограммы. Работает только

в режиме отладки после того

как выполнена компиляция про-

граммы

CTRL-F3

Integrated

debugging

Переключатель. Может находиться

в двух режимах: on и off. В ре-

жиме on разрешает отладку в

интегрированной среде

Standalone

debugging

Переключатель. В режиме on ра-

зрешает выполнять отладку с

помощью автономного отладчика

Display

swapping

Переключатель. Устанавливает

один из режимов переключения

экранов:none, smart, always

Refrуsh

display

Обновляет экран интегрированной

среды и убирает с него ненужную

информацию

сделать, eсли находясь в окне

наблюдения, выбрать соответст-

вующее выражение и нажать кла-

вишу Delete

Edit watch

Редактирует текущее выражение.

Это же можно сделать, если, на-

ходясь в окне наблюдения, выб-

рать выражение и нажать ввод

Delete all

watches

Удаляет все выражения из окна

наблюдения

Toggle

breakpoints

Устанавливает либо отменяет

точку прерывания

CTRL-F8

Clear all

breakpoints

Отменяет все точки прерывания

View next

breakpoint

Отображает на экране фрагмент

программы со следующей точкой

прерывания

— 8 —
Литература
1. Штернберг Л.Ф. Разработка и отладка программ. М., Радио и
связь, 1984.
2. Майерс Г. Искусство тестирования программ. — М.: Финансы и
статистика, 1982.
3. Бородич Ю.С., Вальвачев А.Н., Кузьмич А.И. Паскаль для персо-
нальных компьютеров — Мн.: Вышэйшая школа, 1991.
4. Вьюкова Н.И., Галатенко В.А. Ходулев А.Б. Систематический под-
ход к программированию. М.: Наука, 1988

И.А. Волков, А.И. Лапо, Л.В. Певзнер

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>