Ошибки компиляции (compile-time error) – это ошибки в синтаксисе, которые обнаруживаются во время компиляции. Ошибки времени исполнения (run-time error) – это логические ошибки, их можно обнаружить при запуске программы (например, попытка деления на ноль).
Отладка – это этап разработки программы, на котором обнаруживают, локализуют и устраняют ошибки.
Чтобы понять, где возникла ошибка, приходится:
- узнавать текущие значения переменных;
- выяснять, по какому пути выполнялась программа.
Существуют 2 взаимодополняющие технологии отладки:
- Использование отладчиков – утилит, которые включают в себя пользовательский интерфейс для пошагового выполнения программы: оператор за оператором, функция за функцией, с остановками на некоторых строках исходного кода или при достижении определенного условия.
- Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода – на экран, в файл, на принтер и т.д. Вывод отладочных сведений в файл называется журналированием.
Далее рассмотрен пример с выводом отладочной информации в консоль.
Программа должна считывать последовательность чисел с клавиатуры и выводить их среднее арифметическое. Однако она этого не делает, поскольку содержит 2 ошибки, одна из которых может вызвать аварийный останов, а вторая приводит к неправильному результату или его отсутствию.
Результат работы программы (может отличаться в зависимости от ОС и компилятора):
Выявление бага № 1
Чтобы узнать текущее значение переменной nNums, добавим строку:
while (true)
{
cout << “nNums = “ << nNums << endl;
Такое дополнение приводит к следующему выводу на экран:
Ошибка в программе найдена: количество введенных чисел nNums должно увеличиваться, чего можно достичь, напимер, заменив цикл while циклом for:
Выявление бага № 2
После того, как первый баг найден и устранен, можно убрать из кода строку для проверки текущего значения переменной nNums.
Тем не менее программа работает некорректно (среднее должно быть равно 20):
Очевидно, какая-то из переменных содержит неверное значение. Чтобы это выяснить, придется воспользоваться методом отладочной печати.
Для начала следует переписать тело цикла for следующим образом:
Результат работы программы:
При первом проходе nSum принимает ненулевое значение. Проблема в том, что nSum была объявлена, но не инициализирована, следовательно, ее значение непредсказуемо. Для исправления этой ошибки необходимо изменить объявление переменной следующим образом: int nSum = 0;
Результат работы программы:
Ошибки исправлены, можно убрать вывод отладочной информации:
Результат работы программы (можно протестировать с другими числами):
Использование отладчика
Метод отладочной печати предназначен скорее для небольших программ. В объемных программах зачастую программист даже не знает, куда нужно добавлять отладочные команды. Кроме того, после каждого переписывания программу нужно собирать заново, а для больших программ процесс сборки может занимать продолжительное время.
Кроме того, с помощью метода отладочной печати почти невозможно найти ошибку, связанную с указателями, поскольку указатель, выведенный на экран в шестнадцатеричном виде, малоинформативен.
Чтобы вызвать отладчик, нужно нажать F5 или F10. При нажатии F10 начнется пошаговое выполнение программы, начиная с момента точки входа в программу: слева появляется желтая стрелочка, показывающая, на каком шаге остановилась пошаговая отладка.
Далее можно нажимать F10, или кнопку "шаг с заходом" или "шаг с обходом",
чтобы пройти по всем строкам и увидеть внизу текущие значения переменных. Эти же команды есть в пункте меню Отладка.
Точка останова
Точка останова – это момент, устанавливаемый программистом, до которого будет выполнена программа, прежде чем ее выполнение будет приостановлено. Точку останова можно установить несколькими способами:
- Щелкнуть левой кнопкой мыши слева от строки, перед выполнением которой нужно создать точку останова. Эта строка кода выполнена не будет.
- Курсор мигает на строке, перед которой нужно остановить программу. Нажать F9, чтобы создать точку останова.
Чтобы убрать точку останова, нужно снова щелкнуть на ней мышкой или снова нажать F9.
Чтобы запустить отладку при наличии точки (точек) останова, нужно нажать F5 или в пункте меню Отладка выбрать Начать отладку.
Написать следующий код, установить точку останова, нажать F5:
Теперь при наведении курсора на элементы программы можно увидеть информацию о том, что хранится в переменной. Навести курсор на переменную x:
Информацию можно увидеть таким же образом, работая с массивами, классами и другими более сложными типами данных.
Внизу можно увидеть, что до точки останова переменной x было присвоено значение 2, а переменной y значения пока еще присвоено не было, и до этого момента в переменной y хранится "мусор":
Далее чтобы "прошагать" до конца кода, удобнее использовать F10.
Можно создать закладку на значении переменной следующим образом:
Навести курсор на переменную y, нажать на кнопку в виде канцелярской кнопки.
Появится небольшое меню, с помощью которого можно:
Эту закладку можно перетащить мышкой в любую область редактора кода и отслеживать изменений значения этой переменной. В момент изменения значение будет выделено красным цветом:
Таких закладок и точек останова можно делать любое количество.
Чтобы корректно остановить отладку, нужно нажать Shift+F5 или выбрать в пункте меню Отладка – Остановить отладку.
Установить две точки останова на следующих строках:
Нажать F5, чтобы запустить отладку. Отладчик остановился перед выполнением кода в первой точке останова. Чтобы не шагать построчно, нажимая каждый раз F10, а переместиться сразу ко второй точке останова, нужно еще раз нажать F5. Это актуально, когда между точками останова много строк кода.
"Шаг с заходом" F11 нужен в первую очередь при наличии в программе функций: он позволяет не сразу выполнить функцию, а пройти ее построчно. Также можно сделать точку останова внутри функции, чтобы компилятор во время отладки не выполнил ее моментально.
Чтобы убрать закладку, нужно щелкнуть на ней правой кнопкой мыши и выбрать Очистить.