1. Знайомство з компілятором
Компʼютер не розуміє людської мови. Ба більше, він не розуміє навіть мов програмування. Йому зрозумілі лише програми, записані машинним кодом — послідовності нулів та одиниць. Люди ж мислять словами й ідеями, тож, звісно, їм складно писати цілі програми лише з 0 і 1.
00100100 відповідає десятковому числу
36 або символу
$
Саме тому й зʼявилися мови програмування на кшталт C++. Вони стали своєрідними «перекладачами»: тепер програміст може написати команди на кшталт «Зроби те й те» зрозумілою для себе мовою, а не у вигляді довгого ланцюжка інструкцій для процесора.
Але тут є одна заковика. Компʼютер усе одно не розуміє C++! Якщо просто «згодувати» йому файл із кодом, він нічого не зрозуміє й нічого не виконає. Саме для цього й існує компілятор.
То що таке компілятор?
Компілятор — це спеціальна програма, яка компілює код: перетворює код C++ на код, зрозумілий компʼютеру. Вона бере текст програми на C++, розбирає його, перевіряє на помилки й перетворює на машинний код (зазвичай — на виконуваний файл).
- Програма мовою C++
-
Компілятор
- Програма, що складається з машинних кодів
Компілятор можна уявити собі як суворого вчителя, який:
- уважно перевіряє кожен рядок (чи не припустилися ви помилки?),
- змушує дотримуватися правил (наприклад, правильно називати змінні, ставити крапки з комою, дужки тощо),
- і лише після цього дозволяє «поговорити» з компʼютером!
Компілятор ще розумніший
Сучасні компілятори C++ вміють значно більше: вони не лише перетворюють код, а й оптимізують його, підказують помилки й навіть радять, як писати краще (через попередження — warnings). І це ще не все.
А ще, щоб велику програму було зручно й правильно зібрати, компіляція зазвичай відбувається не за один «магічний» крок, а щонайменше в кілька етапів:
- Спочатку препроцесор обробляє директиви на кшталт #include.
- Потім компілятор перетворює C++-код на обʼєктний код (частково готові «шматочки» програми).
- А далі лінкер (компонувальник) зʼєднує ці шматочки та підʼєднані бібліотеки в один виконуваний файл.
Якщо у вас потужний процесор і ви ввімкнули оптимізації, компілятор може згенерувати машинний код з урахуванням можливостей вашої платформи та вибраних параметрів збирання. Але головне запамʼятати просту ідею: C++ зазвичай компілюється одразу в машинний код, а вже потім запускається готовий виконуваний файл.
flowchart TD
SRC["Вихідний код (файли .cpp)"]:::source
PP["Препроцесор обробляє #include і #define"]:::stage
CC["Компілятор перетворює C++ → обʼєктний код, знаходить помилки, видає попередження"]:::stage
LN["Лінкер зʼєднує обʼєктний код і підʼєднує бібліотеки"]:::stage
EXE["Виконуваний файл (.exe)"]:::artifact
RUN(["▶ Запуск: готовий машинний код виконується безпосередньо"]):::run
LIB["Бібліотеки"]:::lib
DEV["Розробник виправляє помилки"]:::dev
SRC --> PP --> CC --> LN --> EXE --> RUN
CC -.->|"⚠️ попередження й помилки"| DEV
LIB --> LN
classDef source fill:#f59e0b,color:#1c1917,stroke:none
classDef stage fill:#3b82f6,color:#fff,stroke:#1d4ed8,stroke-width:2px
classDef artifact fill:#8b5cf6,color:#fff,stroke:#6d28d9,stroke-width:2px
classDef lib fill:#64748b,color:#fff,stroke:none
classDef run fill:#22c55e,color:#fff,stroke:none
classDef dev fill:#fde68a,color:#1c1917,stroke:#f59e0b,stroke-width:1px
2. Помилки під час компіляції
Швидкість і оптимізація коду нам поки що не надто важливі. Натомість важливе інше: компілятор перевіряє вашу програму на помилки. Він аналізує код на коректність і не пропустить його далі, якщо знайде бодай найменшу помилку.
Приклад помилки:
Ви намагаєтеся присвоїти число змінній, яка може зберігати лише текст.
#include <string>
int main() {
std::string userName = 42; // Ой, так не можна.
}
Компілятор одразу повідомить про помилку: типи не збігаються (формулювання залежить від компілятора) — щось на кшталт: «немає відповідного перетворення з int у std::string».
Інший приклад — описка в імені std::cout:
#include <iostream>
int main() {
std::coutt << "Привіт!\n"; // Описка в назві
}
Компілятор скаже щось на кшталт: «coutt не є членом std» — тож перевіряйте синтаксис!
Як читати помилки?
Більшість компіляторів підказують, де саме сталася помилка: зазвичай це файл, номер рядка і часто навіть номер стовпця, а також текст помилки. Не бійтеся їх: кожна така помилка — це ще один крок до розуміння й перемоги над вашим внутрішнім «босом».
3. Типові помилки під час компіляції
expected означає: «я очікував побачити тут символ X, але його немає». Найчастіше це:
expected ';' — забули крапку з комою
Некоректний код:
#include <iostream>
int main() {
std::cout << "Hello!\n"
return 0;
}
Інструкція має закінчуватися ;. Компілятор дійшов до return і все ще чекав на ;. Виправлення:
std::cout << "Hello!\n";
expected '}' — не закрили блок
Якщо забути }, компілятор зазвичай скаржиться наприкінці файла.
int main() {
std::cout << "Start\n";
return 0;
// тут немає }
Просто закрийте блок:
}
Порада: вирівнюйте відступи — так легше помітити загублену дужку.
expected ')' або expected '(' — проблема з дужками
int main( {
Потрібно:
int main() {
Дужки мають відкриватися й закриватися попарно.
not declared — імʼя не знайдено
Компілятор ніби каже: «я не знаю, що це таке». Можливо, ви забули std::
cout << "Hi\n";
Потрібно:
std::cout << "Hi\n";
cout знаходиться в просторі імен std.
Забули #include <iostream>
int main() {
std::cout << "Hi\n";
}
Додайте:
#include <iostream>
Без #include компілятор не зобовʼязаний знати, що таке std::cout.
4. Коментарі
Отже, уявіть: ви пишете складну програму. Усе працює, ви — геній! Але минає місяць, ви відкриваєте той самий код — і… нічого не розумієте. Пара рядків тут, дивна змінна там. У голові лише одна думка: «Це явно писав хто завгодно, тільки не я!». Саме тут і рятують коментарі.
Коментарі — це як нотатки на полях підручника або записки на холодильнику («Пиво. Не пити. На ранок!»). Компілятор їх ігнорує, а люди — навпаки. Коментарі допомагають пояснити зміст коду, позначити важливі деталі й навіть «вимкнути» фрагменти програми, не видаляючи їх.
Важливо: компілятор не «розуміє» змісту ваших коментарів — для нього це просто текст, який треба пропустити.
Однорядкові коментарі
У C++ є два види коментарів — однорядкові та багаторядкові. Однорядкові починаються з подвійного слеша // і тривають до кінця рядка. Усе, що стоїть після //, вважається коментарем і повністю ігнорується компілятором.
Приклад:
#include <iostream>
int main() {
std::cout << "Привіт, світе!\n"; // Це виводить привітання на екран
}
Ось тут // Це виводить привітання на екран — це коментар. Якщо якийсь фрагмент коду здається неочевидним, так і пишіть!
Ще приклад:
int main() {
int x = 42; // Значення віку програміста
}
Можна писати однорядкові коментарі й в окремих рядках:
#include <string>
int main() {
// Ініціалізація змінної з імʼям користувача
std::string userName = "Василь";
}
Майже як ремарки в сценарії: коментар пояснює, що відбувається, навіщо і чому.
Багаторядкові коментарі
А що, коли у вас накопичилося багато пояснень? Або навіть ціла історія? Для цього є багаторядкові коментарі, які починаються з /* і закінчуються на */. Усе між цими символами компілятор ігнорує, навіть якщо текст займає кілька рядків.
Приклад:
#include <iostream>
int main() {
/*
Тут ми виводимо підказку для користувача.
Якщо імʼя відсутнє, в інших програмах можна написати "Гість".
*/
std::cout << "Введіть своє імʼя:\n";
}
Або так:
int main() {
int age = 18; /* Початкове значення віку
для нового користувача */
}
Увага: не можна вкладати один багаторядковий коментар в інший. Не намагайтеся бути хитрішими за компілятор — це не спрацює.
Ілюстрація:
| Вид | Синтаксис | Приклад |
|---|---|---|
| Однорядковий | |
|
| Багаторядковий | |
|
5. Приклади з життя
«Вимкнення» рядка коду:
Буває, що ви тимчасово не хочете виконувати певний фрагмент коду. Тут коментарі якраз доречні:
// std::cout << "Текст, який тимчасово не потрібен\n";
Рядок залишився, але компілятор його не «бачить».
Позначки TODO і FIXME
Програмісти — теж люди, і часом треба самому собі нагадати, що код іще не дороблений або що тут є помилка. Для цього часто пишуть:
// TODO: зробити перевірку на порожнє введення
// FIXME: ця функція неправильно обчислює суму
Багато редакторів і IDE навіть підсвічують такі слова!
Програмісти жартують
Ну і, звісно, іноді в коді трапляються дуже колоритні коментарі:
// Я не відповідаю за цей код. Мене змусили написати його проти моєї волі.
// Дорогий я_з_майбутнього! Будь ласка, пробач мені за цей код.
// Якщо я ще раз побачу таке, мені доведеться почати носити на роботу зброю.
// Якщо ця умова колись виконається, будь ласка, повідомте мені за номером ххх-ххх-ххх за винагороду.
// Дорогий програміст:
//
// Коли ти закінчиш «оптимізувати» цю підпрограму
// і зрозумієш, якою великою помилкою було це робити,
// будь ласка, збільш лічильник унизу як попередження
// для наступного розробника:
//
// кількість_годин_витрачених_тут = 42
// Коли я починав це писати, тільки Бог і я розуміли, що я роблю.
// Зараз залишився тільки Бог
// Іноді мені здається, що компілятор ігнорує всі мої коментарі
// Я присвячую весь свій код, усю роботу своїй дружині Дарлін, якій
// доведеться утримувати мене, наших трьох дітей та собаку, коли
// це піде в продакшн.
Так, коментарі можуть бути дуже смішними. Адже їх пишуть живі люди.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ