Передача аргументов в функцию по значению


По умолчанию аргументы в функцию передаются по значению. В этом случае 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; просмотров: 78;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.017 сек.