Отладка программы
Отладка программы — это последовательный поиск, объяснение и исправление ошибок в коде. Важно не только устранить сообщение об ошибке, но и проверить, что программа правильно работает на обычных, граничных и необычных входных данных.
Что такое отладка
Перед отладкой полезно вспомнить синтаксис языка: он определяет, как записываются команды, выражения, условия и циклы. Затем программу запускают на небольшом наборе данных и сравнивают полученный результат с ожидаемым.
Отладка — процесс обнаружения причин ошибок в программе, их исправления и повторной проверки результата. Отладка включает чтение кода, выполнение программы по шагам, анализ значений переменных и тестирование.
Обычно отладка проходит в таком порядке: понять условие задачи, воспроизвести ошибку, определить место её появления, найти причину, исправить одну причину за раз и снова запустить программу. Если исправить сразу много строк, трудно понять, какое изменение помогло или создало новую проблему.
- Сформулировать, какой результат должен быть получен.
- Подобрать короткий тест, на котором ошибка заметна.
- Проверить входные данные и значения переменных.
- Исправить код и повторить тест.
- Проверить граничные случаи.
Основные виды ошибок
Ошибки удобно разделять по моменту обнаружения и по характеру неверного поведения. Отдельные страницы синтаксическая ошибка, логическая ошибка и ошибка времени выполнения подробно разбирают эти случаи.
| Вид ошибки | Что происходит | Пример |
|---|---|---|
| Синтаксическая | Язык не может разобрать запись программы; выполнение обычно не начинается. | Пропущена двоеточие после условия или закрывающая скобка. |
| Логическая | Программа запускается, но получает неверный результат. | Вместо площади прямоугольника вычисляется его периметр. |
| Runtime | Ошибка появляется во время выполнения. | Деление на ноль, обращение к несуществующему элементу списка. |
Синтаксические ошибки часто обнаруживаются редактором сразу. Важно читать не только последнюю строку сообщения: указанный номер строки может быть местом, где ошибка стала заметной, а настоящая причина находится строкой выше. Например, незакрытая скобка в предыдущей строке может привести к ошибке в следующей.
Логическая ошибка — ошибка в алгоритме или условии, при которой программа формально выполняется, но решает другую задачу. Она не всегда видна без сравнения с ожидаемым ответом.
Ошибка времени выполнения возникает после успешного разбора кода, когда программа выполняет недопустимое действие: делит на ноль, выходит за границы массива, обращается к неизвестному имени или получает данные неподходящего типа.
Стратегии поиска причины
Для коротких программ применяют трассировку: записывают значения переменных после каждой важной команды. Для длинных программ помогает модульность программы: проверяют отдельные функции и части алгоритма. При этом нужно учитывать область видимости переменных — одинаковые имена в разных блоках могут обозначать разные объекты.
Условие следует читать буквально. Если требуется посчитать числа, кратные \(3\), проверяют условие \(x\bmod 3=0\). Если требуется вывести количество, нельзя без причины заменять его суммой. Для сложных условий полезно выписать таблицу истинности или рассмотреть каждый случай отдельно.
При проверке циклов отдельно контролируют начальное значение счётчика, условие продолжения и изменение счётчика. Если счётчик не изменяется или условие всегда истинно, возникает бесконечный цикл. В программах с функциями нужно проследить граф вызовов: какая функция кого вызывает и не повторяется ли вызов без условия остановки.
Поставьте временный вывод перед подозрительной строкой и после неё. Сравните значения переменных с теми, которые должны быть по условию. После исправления отладочные выводы удалите или отключите.
Программа выполняется, но для прямоугольника со сторонами 3 и 5 выводит 16 вместо 15. Какой это тип ошибки?
Разбор программы по шагам
Рассмотрим программу, которая должна найти сумму всех чётных чисел от \(1\) до \(n\). В исходном варианте есть логическая ошибка в границе цикла.
1n = 6 2s = 0 3for x in range(1, n): 4 if x % 2 == 0: 5 s += x 6print(s)
Для \(n=6\) чётные числа на отрезке от \(1\) до \(6\) — это \(2\), \(4\) и \(6\). Ожидаемая сумма равна \(12\). Программа выводит \(6\), потому что число \(6\) не проверяется.
1n = 6 2s = 0 3for x in range(1, n + 1): 4 if x % 2 == 0: 5 s += x 6print(s)
Это пример логической ошибки, а не синтаксической: запись программы допустима, но граница цикла не соответствует условию задачи. После исправления полезно проверить ещё несколько случаев: \(n=1\) даёт сумму \(0\), \(n=2\) — сумму \(2\), а \(n=0\) требует заранее понять, разрешён ли такой ввод.
Тестирование после исправления
Отладка заканчивается не в момент, когда исчезло сообщение об ошибке. Исправленная программа должна пройти тестирование программы. Минимальный набор тестов включает обычный случай, минимальное допустимое значение, максимальное или близкое к нему значение, пустой или нулевой случай, а также случай, где меняется ветвь условия.
| Тип теста | Зачем нужен | Пример для суммы чётных чисел |
|---|---|---|
| Обычный | Проверяет основную работу алгоритма. | \(n=6\), ответ 12. |
| Граничный | Проверяет начало или конец диапазона. | \(n=1\), ответ 0. |
| Особый | Проверяет смену поведения. | \(n=2\), ответ 2. |
| Большой | Выявляет медленную работу или переполнение. | Большое допустимое \(n\). |
Не считайте исчезновение сообщения об ошибке доказательством правильности. Не меняйте условие задачи под полученный ответ. Не забывайте, что в большинстве языков индексы массива начинаются с нуля. Проверяйте деление на ноль, пустые данные, границы циклов и последнюю итерацию. При рекурсии обязательно должно быть условие остановки; иначе вызовы будут продолжаться.
Синтаксическая ошибка мешает разобрать программу, runtime-ошибка возникает во время выполнения, а логическая ошибка даёт неверный результат при внешне нормальной работе программы.
Алгоритм действий на экзамене
- Проверьте ввод: сколько чисел читается, в каком порядке и какого они типа.
- Проследите инициализацию переменных до первого использования.
- Проверьте условия: знаки \(<\) и \(\le\), оператор
andилиor, остаток от деления. - Для каждого цикла определите первое и последнее значение счётчика.
- Сравните программу с формулой или ручным решением на маленьком тесте.
- После исправления проверьте случай на границе и случай с пустым результатом.
Быстрая проверка
for i in range(3)?Главное
- Отладка — это поиск причины ошибки, исправление и повторная проверка.
- Синтаксические ошибки связаны с формой записи, runtime-ошибки — с недопустимым действием во время выполнения, логические — с неверным алгоритмом или условием.
- Трассировка значений, контрольные точки и проверка границ цикла помогают найти место расхождения.
- После исправления нужны обычные, граничные и особые тесты.
- Особенно внимательно проверяйте индексы, границы
range, условия, деление на ноль и остановку рекурсии.