Способы передачи параметров в функцию
Существует 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 и работает с ним.
Преимущества передачи по адресу:
- Передача по адресу позволяет функции изменить значение аргумента. Если нужно запретить изменение, необходимо использовать константный указатель.
- Передача параметра по адресу эффективна, т.к. не происходит копирования данных.
- Можно вернуть несколько значений из функции, используя передачу по адресу.
Недостатки передачи по адресу:
- Необходимо проверять параметр, не является ли он нулевым, иначе попытка разыменовывания нулевого указателя приведет к ошибке.
Выводы:
- Используйте данный тип передачи параметров при передачи обычных массивов.
- Не используйте этот способ при передачи фундаментальных типов данных, т.к. это может привести к излишнему усложнению кода.