Передача аргументов в функцию по значению
По умолчанию аргументы в функцию передаются по значению. В этом случае C++помещает копию значения аргумента во временный участок памяти, называемый стеком. Любые изменения, которые функция осуществляет над аргументом, влияют только на эту копию, расположенную в стеке. Например:
…
int main(){
int y = 5; fun(y);
cout<<y<<endl; // 5
}
voidfun(int x){
x++;
cout<<x<<endl; // 6
}
Как мы видим, изменения, внесенные в параметр x во время выполнения функции, не влияют на значение переменной y, которая передаётся в функцию, т.е. на аргумент.
При передаче аргументов по значению функция работает с копией значений аргументов.
В качестве аргументов могут выступать константы, переменные или выражения, тип которых соответствует типу параметров.
// Пример 5.6.Обменять значения двух целочисленных переменных,
// используя функцию обмена change().
#include <iostream>
using namespace std;
void change(int, int);
int main(){
int a = 10, b = 5;
cout<<"main(): do perestanovki \n";
cout<<"a = "<<a<<", b = "<<b<< endl; // a = 10, b = 5
change(a, b);
cout << "main(): posle perestanovki \n";
cout<<"a = "<<a<<", b = "<<b<< endl; // a = 10, b = 5
system("pause");
}
void change(int x, int y){
cout<<"change(): do perestanovki \n";
cout<<"x = "<<x<<", y = " <<y<<endl; // x = 10, y = 5
int z = x; x = y; y = z;
cout<<" change(): posle perestanovki \n";
cout<<"x = "<<x<<", y = "<<y <<endl; // x = 5, y = 10
}
В функцию change() переменные a и b передаются по значению, т.е. функция change()работает с копиями аргументов. Как мы видим, изменение копий в функции не влияет на значения переменных a и bфункции main().
Ссылки
В языке С++ ссылкаопределена как другое имя или псевдоним уже существующей переменной. Для ссылки не требуется дополнительного пространства в памяти. Для определения ссылки применяется унарная операция &:
имя_типа & имя_ссылки = инициализатор ссылки;
Например:
int x = 5;
int & rf = x; // rx является ссылкой на x
rx++; // то же самое, что и x++
Имена x и rx – это синонимы одной и той же переменной. Поэтому операторы
x++; и rx++;
равнозначны.
После инициализации значение ссылки изменить нельзя, она всегда "смотрит" на ту переменную, с которой она связана инициализацией.
Самостоятельное использование переменных ссылочного типа не имеет практического применения. Чаще всего ссылки используются как параметры функций.
Передача аргументов в функцию по ссылке
Мы уже знаем, что функция может вернуть только одно значение. В том случае, если функция должна вернуть два или более значений, например, типа int, можно вернуть не значения, а записать их в определённых ячейках памяти. Для этого необходимо в качестве параметров функции использовать ссылки:
fun(int &x, int &y);
При передаче аргумента по ссылке в соответствующий параметр копируется адрес аргумента (а не его значение). В пределах вызываемой функции этот адрес используется для доступа к реальному аргументу, заданному при её вызове. Это значит, что изменения, внесённые в параметр, окажут воздействие на аргумент, используемый при вызове функции.
При использовании ссылки для передачи аргумента в функцию необходимо:
· в заголовке функции соответствующие параметры-ссылки записать как переменные ссылочного типа, то есть с символом &;
· в теле функции никакие дополнительные символы для этих переменных не использовать, т.е. работать, как с обычными переменными;
· при вызове функции в качестве аргументов использовать только переменные, причем их тип должен совпадать с типом параметров-ссылок.
При передаче в функцию аргумента по ссылке в соответствующий параметр функции копируется адрес аргумента (а не его значение). Параметры-ссылки являются другими именами им соответствующих аргументов, поэтому параметры-ссылки не требуют выделения отдельной памяти.
Рассмотрим следующий фрагмент программы, где используется функция с параметром-ссылкой:
int main(){
int y = 5;
fun(y);
cout<<y<<endl; // 6
}
voidfun(int &x){
x++; cout<<x<<endl; // 6
}
В приведённой функции fun()при объявлении параметра-ссылки мы указываем, что в функцию будет передаваться адрес переменной. Это даёт возможность изменять аргументы, не указывая в явном виде при вызове функции передачу в неё адреса. В самой же функции с параметром-ссылкой работаем как с обычной переменной.
// Пример 5.7. Для каждой пары введенных целых чисел найти их сумму
// и произведение двумя способами:
// 1) используя одну функцию SumMult(),возвращающей и сумму,
// и произведение двух чисел;
// 2) с помощью двух функций sum(), mult().
#include <iostream>
using namespace std;
voidSumMult(int, int, int&, int&); // прототип функции SumMult()
int sum(int, int); // прототип функции sum()
int mult(int, int); // прототип функции mult()
int main(){
int a, b, r1, r2;
while(true){
cout<<"Vvedi a, b"<<" (a = 0 and b = 0 --->exit)"<<endl;
cin>>a>>b;
if(!(a || b)) break;
SumMult(a, b, r1, r2); // вызов функции SumMult()
cout<<a<<" + "<<b<<" = "<<r1<<endl;
cout<<a<<" * "<<b<<" = "<<r2<<endl;
cout<<a<<" + "<<b<<" = "<<sum(a, b)<<endl; // вызов sum()
cout<<a<<" * "<<b<<" = "<<mult(a, b)<<endl; // вызов mult()
}
system("pause");
}
void SumMult(int x, int y, int &s, int &p){ // функция SumMult()
s=x+y;
p=x*y;
}
int Sum(int x, int y){ // функция sum()
return x+y;
}
int Mult( int x, int y){ // функция mult()
return x*y;
}
// Пример 5.8. Расположить значения целочисленных переменных а, в, с
//в порядке возрастания, используя функцию перестановки значений
// двух переменных. Аргументы передавать по ссылке.
#include <iostream>
using namespace std;
void change(int &, int &); // прототип функции change()
int main(){
int a, b, c;
cout<<"Vvedi a, b, c: "; cin>>a>>b>>c;
if(a > b) change(a, b); // вызов функции change()
if(b > c) change(b, c);
if(a > b) change(a, b);
cout<<" a = " << a << " b = "<< b <<" c = "<< c<<endl;
system("pause");
}
void change(int & x, int & y){ // описание функции change()
int temp;
temp = x; x = y; y = temp;
}
Ссылка в качестве возвращаемого значения функции
При использовании ссылки в качестве возвращаемого значения функции появляется возможность использовать функцию в качестве левого операнда в операторе присваивания.
// Пример 5.9. Функция возвращает ссылку.
#include <iostream>
using namespace std;
int x; // глобальная переменная x
int& setx(){return x;}
int main(){
setx() = 555; // присваивание значения x при вызове
// функции, возвращающей ссылку
cout<<"x = "<<x<<endl; // x = 555
}
Здесь функция setx()возвращает ссылку на целое значение, т.е. возвращает псевдоним переменной, стоящей в операторе returnэтой функции, а это есть ссылка на глобальную переменную x.
Поскольку возвращаемое значение является псевдонимом некоторой переменной, то возвращать константу такая функция не может. Попытка написать
return 5;
вызывает ошибку компиляции.
Ошибка компиляции происходит и при возвращении локальной переменной по ссылке, т. к. при выходе из функции локальные переменные уничтожаются, а ссылаться на несуществующие переменные нельзя.
Дата добавления: 2022-05-27; просмотров: 80;