Объявление и определение
Чему вы научитесь:
- вызывать функцию до её определения и понимать, кто сообщает об ошибке;
- выбирать, получит функция копию аргумента или саму переменную;
- перегружать функции и задавать аргументы по умолчанию;
- записывать короткие функции лямбдами и захватывать в них переменные.

Представьте автомат, который удваивает числа. На его передней панели написано имя twice(int). Ниже есть прорезь, куда кладут фишку с целым числом, и лоток, откуда выпадает результат. Внутри стоит механизм, который и делает работу.
Чтобы пользоваться автоматом, механизм видеть не нужно: по панели понятно, как он называется, что в него класть и что из него выйдет. Функция в C++ устроена так же:
- панель — это первая строка функции: тип результата, имя и параметры;
- механизм — это тело в фигурных скобках.
Компилятор читает файл сверху вниз. Когда он встречает вызов функции, ему уже нужно видеть её панель: имя, типы параметров и тип результата. Поэтому функцию, определённую ниже main, вызвать из main не получится:
#include <iostream>
int main() {
std::cout << twice(21) << '\n'; // ✗
}
int twice(int x) {
return x * 2;
}error: use of undeclared identifier 'twice'У twice один параметр — переменная x из объявления функции, которая получает значение при вызове. Аргумент — значение, которое передают в вызове: в twice(21) аргумент — 21, а параметр — x. На автомате параметр — это прорезь, а аргумент — фишка, которую в неё кладут.
Можно перенести twice выше main, и ошибка исчезнет. Но если функция определена в другом файле, переносить нечего — о ней нужно сообщить компилятору иначе.
Объявление
Объявление сообщает компилятору имя функции, типы её параметров и тип результата. Это панель автомата без механизма: тела у объявления нет, вместо него стоит точка с запятой.
int twice(int x);Имена параметров в объявлении можно не писать: int twice(int); значит то же самое. Компилятору нужны только типы, а имя x подсказывает читателю, что передаётся в функцию. В определении имя тоже можно не писать, если тело параметр не использует.
Определение — это объявление вместе с телом в фигурных скобках, поэтому функцию, определённую выше main, отдельно объявлять не нужно. Объявить функцию можно несколько раз, а определить — только один.
Вызов до определения
Объявление выше main решает задачу: вызов компилируется, а тело может стоять в конце файла.
#include <iostream>
int twice(int x);
int main() {
std::cout << twice(21) << '\n'; // 42
}
int twice(int x) {
return x * 2;
}Чтобы проверить вызов twice(21), компилятору хватает объявления: функция принимает int и возвращает int. Если тело лежит в другом .cpp-файле, компоновщик свяжет вызов с этим телом. На этом основаны заголовочные файлы: в них пишут объявления, а определения — в .cpp-файлах. Так устроен и #include <iostream>: он вставляет в файл объявления из стандартной библиотеки.
Частая ошибка
Функцию объявили, а определить забыли. Компилятор ошибки не видит, и сборка останавливается на следующем шаге:
int twice(int x);
int main() {
return twice(21); // ✗
}undefined reference to `twice(int)'Это сообщение компоновщика, а не компилятора: объявления хватило, чтобы проверить вызов, но тела twice нет ни в одном файле программы. Здесь аналогия с автоматом хромает: настоящую панель без механизма видно сразу, а программа с таким объявлением компилируется, и пустоту замечает только компоновщик. В задачах курса то же сообщение выглядит иначе: undefined symbol: twice(int).
Та же ошибка появится, если определение не совпадёт с объявлением по типам параметров. int twice(long x) — уже другая функция, и объявленная twice(int) снова останется без тела.
Главное
- Параметр — переменная в объявлении функции, аргумент — значение в вызове.
- Объявление — первая строка функции с точкой с запятой вместо тела; его хватает, чтобы компилятор проверил вызов.
- Определение — объявление вместе с телом; объявлять функцию можно много раз, определять — один.
- Объявление без определения компилируется, а сборку останавливает компоновщик:
undefined referenceилиundefined symbol.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.