Параметры: по значению и по ссылке
Функция inc_copy увеличивает свой параметр на единицу, но переменная, переданная в неё, от этого не меняется:
#include <iostream>
void inc_copy(int x) {
++x;
std::cout << x << '\n'; // 2
}
int main() {
int n = 1;
inc_copy(n);
std::cout << n << '\n'; // 1
}Внутри функции x уже равна 2, а n в main по-прежнему равна 1.
Копия аргумента
При вызове inc_copy(n) создаётся новая переменная x, и в неё копируется значение аргумента (argument) n. Это передача по значению (pass by value): функция работает с копией, а не с самой n. Копия живёт до конца функции и исчезает вместе со всеми изменениями.
Изменённую копию можно вернуть через return: вызывающий код получит новое значение, а исходная переменная останется прежней.
Параметр-ссылка
Чтобы функция меняла переменную вызывающего кода, параметр объявляют ссылкой (reference): после типа ставят &. Ссылка — другое имя уже существующей переменной, а не её копия.
#include <iostream>
void inc_ref(int& x) {
++x;
}
int main() {
int n = 1;
inc_ref(n);
std::cout << n << '\n'; // 2
}Внутри inc_ref имя x обозначает саму n, поэтому ++x увеличивает n. Вызов выглядит так же, как inc_copy(n): о том, что аргумент изменится, говорит только объявление функции. Аргументом здесь может быть только переменная: в вызове inc_ref(5) увеличивать нечего, и он не скомпилируется.
Константная ссылка
Копия int или double стоит дёшево, поэтому такие параметры передают по значению. Но объекты некоторых типов хранят тысячи значений, и копировать такой объект при каждом вызове дорого. Параметр такого типа объявляют константной ссылкой — const T&, где T — тип параметра. Копии нет, как и у обычной ссылки, но изменить аргумент функция не может: такую попытку остановит компилятор.
Константная ссылка принимает и литерал вроде 5: менять его функция всё равно не будет.
Частая ошибка
Функция возвращает ссылку на свою локальную переменную:
const int& sum(int a, int b) {
int result = a + b;
return result; // ✗
}warning: reference to stack memory associated with local variable 'result' returned [-Wreturn-stack-address]Компилятор только предупреждает, но result уничтожается при выходе из функции, и ссылка остаётся без переменной. Такую ссылку называют висячей (dangling reference), а чтение через неё — неопределённое поведение (undefined behavior). Верните результат по значению: int sum(int a, int b).