Способы передачи параметров в функцию
Существует 3 способа передачи параметров в функцию в С++:
- передача по значению
- передача по ссылке
- передача по указателю
Передача по значению
Это означает, что значение, переданное в функцию, копируется и функция работает с копией аргумента. Рассмотрим пример:
void func(int x){ x++; cout << "func: " << x << endl; } int main() { int n = 10; func(n); cout << "main: " << n << endl; }
Вывод:
func: 11
main: 10
Переменная x
в func
изменилась на 11, при этом переменная в main
осталась равна 10. Это говорит о том, что при передачи аргумента значение скопировалось.
Преимущества передачи параметров по значению:
- По значению можно передавать любые аргументы: переменные (например, х), литералы (например, 5), структуры, классы и т.д.
- Аргументы никогда не изменяются функцией, в которую передаются, т.к. создается их копия.
Недостатки передачи параметров по значению:
- Копирование "тяжелых" объектов может привести к значительной потери эффективности.
Вывод:
- Передача параметров по значению эффективна в случае передачи фундаментальных типов данных (int, bool, double и т.д.)
- Передача по значению экземпляров классов и структур не эффективна.
Передача по ссылке
Это означает, что параметр передается не по значению, а как ссылка. При этом копирование значения не происходит. Рассмотрим тот же пример, только передача параметра будет по ссылке:
void func(int &x){ x++; cout << "func: " << x << endl; } int main() { int n = 10; func(n); cout << "main: " << n << endl; }
Вывод:
func: 11
main: 11
Функция func
изменила значение переменной n
, т.к. параметр был передан по ссылке.
Преимущества передачи по ссылке:
- Ссылки позволяют функции изменять значение параметра. Для того, чтобы запретить функции изменять параметр, переданный по ссылке, необходимо использовать константны ссылки.
- Передача аргументов по ссылке намного эффектинее, особенно для "тяжелых" объектов.
- В некоторых случая передача параметров по ссылке может использоваться для возврата сразу нескольких значений из функции.
Недостатки передачи по ссылке:
- При вызове функции невозможно определить, будет аргумент изменен функцией или нет. Иногда это может привести к ошибкам.
Выводы:
- Используйте передачу параметров по ссылке, когда передаете "тяжелые" объекты (экземпляры структур или классов), а также когда нужно, чтобы функция меняла значение параметра.
- Не используйте передачу по ссылке при передаче фундаментальных типов и обычных массивов.
Передача по адресу
В этом случае передается адрес переменной-аргумента. Параметром функции должен быть указатель. Рассмотрим пример:
void func(int *x){ (*x)++; cout << "func: " << *x << endl; } int main() { int n = 10; func(&n); cout << "main: " << n << endl; }
Вывод:
func: 11
main: 11
Для того чтобы работать с параметром, функция func
разыменовывает параметр x
и работает с ним.
Преимущества передачи по адресу:
- Передача по адресу позволяет функции изменить значение аргумента. Если нужно запретить изменение, необходимо использовать константный указатель.
- Передача параметра по адресу эффективна, т.к. не происходит копирования данных.
- Можно вернуть несколько значений из функции, используя передачу по адресу.
Недостатки передачи по адресу:
- Необходимо проверять параметр, не является ли он нулевым, иначе попытка разыменовывания нулевого указателя приведет к ошибке.
Выводы:
- Используйте данный тип передачи параметров при передачи обычных массивов.
- Не используйте этот способ при передачи фундаментальных типов данных, т.к. это может привести к излишнему усложнению кода.