Перейти к содержимому
Теория · Функции · урок 2 из 11

Параметры: по значению и по ссылке

Функция inc_copy увеличивает свой параметр на единицу, но переменная, переданная в неё, от этого не меняется:

C++
#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): после типа ставят &. Ссылка — другое имя уже существующей переменной, а не её копия.

C++
#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: менять его функция всё равно не будет.

Частая ошибка

Функция возвращает ссылку на свою локальную переменную:

C++
const int& sum(int a, int b) {
    int result = a + b;
    return result;  // ✗
}
TEXT
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).