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++ → объектный код Находит ошибки, даёт warnings"]:::stage
LN["Линкер Склеивает объектный код + подключает библиотеки"]:::stage
EXE["Исполняемый файл .exe"]:::artifact
RUN(["▶ Запуск Готовый машинный код выполняется напрямую"]):::run
LIB["Библиотеки"]:::lib
DEV["Разработчик исправляет ошибки"]:::dev
SRC --> PP --> CC --> LN --> EXE --> RUN
CC -.->|"⚠️ warnings & ошибки"| 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
// Когда я начинал это писать, только Бог и я понимали, что я делаю.
// Сейчас остался только Бог
// иногда мне кажется, что компилятор игнорирует все мои комментарии
// Я посвящаю весь свой код, всю работу своей жене Дарлин, которой
// придётся содержать меня, наших троих детей и собаку, когда
// это пойдет в продакшн.
Да, комментарии могут быть очень смешными. Ведь их пишут живые люди.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ