Як не дивно, програмування може бути складним і помилок може бути дуже багато. Помилки, як правило, потрапляють в одну з двох категорій: синтаксичні або семантичні (смислові).
Типи помилок
Синтаксична помилка виникає, коли ви пишете код, який не відповідає правилам граматики мови C++. Наприклад, пропущені крапки з комою, неоголошені змінні, непарні круглі або фігурні дужки і т.д. В наступній програмі є декілька синтаксичних помилок:
|
1 2 3 4 5 6 7 |
#include <iostream>; // директиви препроцесора не закінчуються крапкою з комою int main() { std:cout < "Hi there; << x; // недійсний оператор (:), незакінчене речення (пропущено ") і неоголошена змінна return 0 // пропущена крапка з комою в кінці стейтменту } |
На щастя, компілятор ловить подібні помилки і повідомляє про них у вигляді попереджень або помилок.
Семантична помилка виникає, коли код є синтаксично правильним, але робить не те, що задумав програміст.
Іноді це може призвести до збою в програмі, наприклад, якщо ділити на нуль:
|
1 2 3 4 5 6 7 8 9 |
#include <iostream> int main() { int a = 10; int b = 0; std::cout << a << " / " << b << " = " << a / b; // ділити на 0 заборонено! return 0; } |
Іноді це може призвести до неправильних результатів:
|
1 2 3 4 5 6 7 |
#include <iostream> int main() { std::cout << "Hello, word!"; // орфографічна помилка return 0; } |
Або взагалі робити не те, що потрібно:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> int add(int x, int y) { return x - y; // функція повинна виконувати операцію додавання, а не віднімання } int main() { std::cout << add(5, 3); // повинно бути 8, а не 2 return 0; } |
На жаль, компілятор не ловить подібні помилки, тому що він перевіряє тільки те, що ви написали, а не те, що ви хотіли цим зробити.
У вищенаведених прикладах помилки досить легко виявити. Але в більшості програм (>40 рядків коду), семантичні помилки побачити за допомогою простого перегляду коду не так вже й легко.
І тут нам на допомогу приходить відлагоджувач.
Відлагоджувач
Відлагоджувач (або “дебагер”, від англ. “debugger”) — це комп’ютерна програма, яка дозволяє програмісту контролювати виконання коду. Наприклад, програміст може використовувати відлагоджувач для виконання програми покроково, послідовно вивчаючи значення змінних в програмі.
Старі дебагери, такі як GDB, мали інтерфейс командного рядка, де програмісту доводилося вводити спеціальні команди для початку роботи. Сучасні відлагоджувачі мають графічний інтерфейс, що значно спрощує роботу з ними. Зараз майже всі сучасні IDE мають вбудовані відлагоджувачі. Тобто, ви можете використовувати одне середовище розробки як для написання коду, так і для його відлагодження (замість постійного переключання між різними програмами).
Базовий функціонал у всіх дебагерів однаковий. Відрізняються вони, як правило, лише доступом до цього функціоналу, гарячими клавішами і додатковими можливостями.
Примітка: Перед тем як продовжити, переконайтеся, що ви знаходитеся в режимі конфігурації “Debug”.
Степпінг
Степпінг (англ. “stepping”) — це можливість відлагоджувача виконувати код покроково (рядок за рядком). Є три команди степпінгу:
"Шаг с заходом"
"Шаг с обходом"
"Шаг с выходом"
Ми розглянемо кожну з цих команд по порядку.
Команда “Шаг с заходом”
Команда “Шаг с заходом” (англ. “step into”) виконує наступний рядок коду. Якщо цим рядком є виклик функції, то "Шаг с заходом" відкриває функцію і виконання переноситься на початок цієї функції.
Давайте розглянемо дуже просту програму:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> void printValue(int nValue) { std::cout << nValue; } int main() { printValue(5); return 0; } |
Як ви вже знаєте, при запуску програми виконання починається з виклику головної функції main(). Оскільки ми хочемо виконати відлагодження коду всередині функції main(), то почнемо з команди "Шаг с заходом".
В Visual Studio перейдіть в меню "Отладка" > "Шаг с заходом" (або натисніть F11):

Якщо ви використовуєте іншу IDE, то знайдіть в меню команду "Step Into/Шаг с заходом" і натисніть на неї.
Коли ви це зробите, повинні відбутися дві речі. По-перше, оскільки наша програма є консольного типу, то повинно відкритися консольне вікно. Воно буде порожнім, тому що ми ще нічого не виводили. По-друге, ви повинні побачити спеціальний маркер зліва біля відкриваючої дужки функції main(). У Visual Studio цим маркером є жовта стрілочка (якщо ви використовуєте іншу IDE, то має з’явитися щось схоже):

Стрілка-маркер вказує на наступний рядок, який буде виконуватися. В цьому випадку відлагоджувач повідомляє нам, що наступним рядком, який буде виконуватися, є відкриваюча фігурна дужка функції main(). Виберіть "Шаг с заходом" ще раз і стрілка переміститься на наступний рядок:

Це означає, що наступним рядком, який буде виконуватися, є виклик функції printValue(). Виберіть "Шаг с заходом" ще раз. Оскільки printValue() — це виклик функції, то ми перейдемо на початок функції printValue():

Виберіть ще раз "Шаг с заходом" для виконання відкриваючої фігурної дужки функції printValue(). Стрілка вказуватиме на std::cout << nValue;.
Тепер виберіть команду "Шаг с обходом" (F10). Ви побачите число 5 в консольному вікні.
Виберіть "Шаг с заходом" ще раз для виконання закриваючої фігурної дужки функції printValue(). Функція printValue() завершить своє виконання і стрілка переміститься в функцію main(). Зверніть увагу, що в main() стрілка знову вказуватиме на виклик printValue():

Може здатися, ніби відлагоджувач має намір ще раз повторити цикл з функцією printValue(), але насправді він нам просто повідомляє, що тільки що повернувся з цієї функції.
Виберіть команду "Шаг с заходом" два рази. Готово, всі рядки коду виконані. Деякі відлагоджувачі автоматично зупиняють сеанс відлагодження в цій точці, але Visual Studio так не робить. Якщо ви використовуєте Visual Studio, то виберіть "Отладка" > "Остановить отладку" (або натисніть Shift+F5):

Таким чином, ми повністю зупинили сеанс відлагодження нашої програми.
Команда “Шаг с обходом”
Команда “Шаг с обходом” (англ. “step over”) дозволяє виконати наступний рядок коду. Тільки якщо цим рядком є виклик функції, то команда "Шаг с обходом" виконає весь код функції в одне натискання і поверне нам контроль після того, як функція буде виконана.
Примітка для користувачів Code::Blocks:Команда “Шаг с обходом” називається “Next Line”.
Розглянемо приклад, використовуючи наступну програму:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> void printValue(int nValue) { std::cout << nValue; } int main() { printValue(5); return 0; } |
Натисніть "Шаг с заходом", щоб дійти до виклику функції printValue():

Тепер, замість команди "Шаг с заходом", виберіть "Шаг с обходом" (або натисніть F10):

Відлагоджувач виконає функцію (яка виведе значення 5 в консоль), а після цього поверне нам контроль на рядку return 0;. І це все за одне натискання.
Команда "Шаг с обходом" дозволяє швидко пропустити код функцій, коли ми впевнені, що вони працюють коректно і їх не потрібно відлагоджувати.
Команда “Шаг с выходом”
Команда “Шаг с выходом” (англ. “step out”) виконує весь код функції, в якій ви зараз перебуваєте, і повертає контроль тільки після того, коли ця функція завершить своє виконання. Простіше кажучи, "Шаг с выходом" дозволяє вийти з функції.
Зверніть увагу, команда "Шаг с выходом" з’явиться в меню "Отладка" тільки після початку сеансу відлагодження (що робиться шляхом використання однієї з двох вищезазначених команд).
Розглянемо все той же приклад:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> void printValue(int nValue) { std::cout << nValue; } int main() { printValue(5); return 0; } |
Натискайте "Шаг с заходом" до тих пір, поки не перейдете до відкриваючої фігурної дужки функції printValue():

Після цього виберіть "Отладка" > "Шаг с выходом" (або натисніть Shift+F11):

Ви помітите, що значення 5 відобразилося в консольному вікні, а відлагоджувач перейшов до виклику функції printValue() в функції main():

Команда “Выполнить до текущей позиции”
У той час як степпінг корисний для вивчення кожного рядка коду окремо, у великій програмі переміщатися по коду за допомогою цих команд не дуже зручно. Але і тут сучасні відлагоджувачі пропонують ще декілька інструментів для ефективного відлагодження програм.
Команда “Выполнить до текущей позиции” дозволяє в одне натискання виконати весь код до рядка, позначеного курсором. Потім контроль повертається до нас, і ми можемо проводити відлагодження з цієї точки вже більш детально. Давайте спробуємо, використовуючи вже знайому нам програму:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> void printValue(int nValue) { std::cout << nValue; } int main() { printValue(5); return 0; } |
Помістіть курсор на рядок std::cout << nValue; всередині функції printValue(), натисніть правою кнопкою миші і виберіть "Выполнить до текущей позиции" (або Ctrl+F10):

Ви помітите, що жовта стрілочка переміститься на вказаний нами рядок. Виконання програми зупиниться в цій точці, і програма чекатиме наших подальших команд.
Команда “Продолжить”
Якщо ви перебуваєте в середині сеансу відлагодження вашої програми, то ви можете повідомити відлагоджувачу продовжувати виконання коду до тих пір, поки він не дійде до кінця програми (або до наступної контрольної точки). У Visual Studio цей параметр має назву “Продолжить” (англ. “Continue”). В інших дебагерах він може мати назву "Run" або "Go".
Повертаючись до вищенаведеного прикладу, ми знаходимося якраз всередині функції printValue(). Виберіть "Отладка" > "Продолжить" (або F5):

Програма завершить своє виконання і вийде з сеансу відлагодження.
Точки зупину
Точки зупину (англ. “breakpoints”) — це спеціальні маркери, на яких відлагоджувач зупиняє процес виконання програми.
Щоб задати точку зупину в Visual Studio, клацніть правою кнопкою миші по вибраному рядку > "Точка останова" > "Вставить точку останова":

З’явиться червоний кружечок біля рядка:

У програмі, наведеній вище, створіть точку зупину на рядку std::cout << nValue;. Потім виберіть "Шаг с заходом" для старту сеанса відлагодження, а потім "Продолжить". Ви побачите, що замість завершення виконання програми і зупинки сеансу відлагодження, дебагер зупиниться в зазначеній нами точці:

Точки зупину надзвичайно корисні, якщо ви хочете вивчити тільки певну частину коду. Просто задайте точку зупину в обраній ділянці коду, виберіть команду "Продолжить" і відлагоджувач автоматично зупиниться біля зазначеного рядка. Потім ви зможете використовувати команди степпінгу для більш детального перегляду/вивчення коду.
