Использование указателя для обеспечения вызова по ссылке
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Несмотря на то что в качестве С++ -соглашения о передаче параметров по умолчанию действует вызов по значению, существует возможность "вручную" заменить его вызовом по ссылке. В этом случае функции будет передаваться адрес аргумента(т.е. указатель на аргумент). Это позволит внутреннему коду функции изменить значение аргумента, которое хранится вне функции.

Чтобы понять, как передача указателя позволяет вручную обеспечить вызов по ссылке, рассмотрим функцию swap(). (Она меняет значения двух переменных, на которые указывают ее аргументы.) Вот как выглядит один из способов ее реализации.

// Обмен значениями двух переменных, адресуемых параметрами х и у.

void swap (int *x, int *y)

{

int temp;

temp = *x;               // Временно сохраняем значение,

// расположенное по адресу х.

*х = *у;                    // Помещаем значение:, хранимое по адресу у,

//по адресу х.

*у = temp;               // Помещаем значение, которое раньше

// хранилось по адресу х, по адресу у.

Функция swap () объявляет два параметра-указателя (х и у). Она использует эти параметры для обмена значений переменных, адресуемых аргументами (переданными функции). Не забывайте, что выражения *х и *у обозначают переменные, адресуемые указателями х и у соответственно. Таким образом, при выполнении инструкции

*х = *у;

значение объекта, адресуемого указателем у, помещается в объект, адресуемый указателем х. Следовательно, по завершении этой функции содержимое переменных, используемых при ее вызове, "поменяется местами".

Поскольку функция swap () ожидает получить два указателя, следует помнить, что функцию swap () необходимо вызывать с адресами переменных, значения которых вы хотите обменять. Корректный вызов этой функции продемонстрирован в следующей программе.

// Задание 8.1_2.cpp: определяет точку входа для консольного приложения.

// Демонстрируется версия функции swap() с использованием указателей.

#include "stdafx.h"

#include <iostream>

using namespace std;

// Объявляем функцию swap(), которая использует указатели,

void swap(int *x, int *y);    // Прототип функции

int main()

{

setlocale(LC_ALL, "Russian");

int i, j;

i = 10;

j = 20;

cout << "Исходные значения переменных i и j: ";

cout << i << " " << j << "\n";

swap(&j, &i);      // Вызываем swap() с адресами переменных i и j.

cout << "Значения переменных i и j после обмена: ";

cout << i << " " << j << "\n";

return 0;

}

// Обмен значениями двух переменных, адресуемых параметрами х и у.

void swap(int *x, int *у)

{

int temp;

// Меняем значения переменных, адресуемых параметрами х и у,

// используя явно заданные операции с указателями.

temp = *x;   // Временно сохраняем значение по адресу х.

*x = *у;           // Помещаем значение, хранимое по адресу у, по адресу x.

*у = temp;   // Помещаем значение, хранимое по адресу х, по адресу у.

}

В функции main () переменной i было присвоено начальное значение 10, а переменной j — 20. Затем была вызвана функция swap () с адресами переменных i и j .Для получения адресов здесь используется унарный оператор "&". Следовательно, функции swap () при вызове были переданы адреса переменных i и j, а не их значения. После выполнения функции swap () переменные i и j обменялись своими значениями, что подтверждается результатами выполнения этой программы.

Исходные значения переменных i и j: 10 20

Значения переменных i и j после обмена:       20 10

Несмотря на возможность "вручную" организовать вызов по ссылке с помощью оператора получения адреса, такой подход не всегда удобен:

Ø во-первых, он вынуждает программиста выполнять все операции с использованием указателей.

Ø во-вторых, вызывая функцию, программист должен не забыть передать ей адреса аргументов, а не их значения.

К счастью, в C++ можно сориентировать компилятор на автоматическое использование вызова по ссылке (вместо вызова по значению) для одного или нескольких параметров конкретной функции. Такая возможность реализуется с помощью ссылочного параметра (reference parameter). При использовании ссылочного параметра функции автоматически передается адрес (а не значение) аргумента.

При выполнении кода функции (при выполнении операций над ссылочным параметром) обеспечивается его автоматическое разыменование, и поэтому программисту не нужно прибегать к операторам, используемым с указателями.

Ссылочный параметр объявляется с помощью символа "&", который должен предшествовать имени параметра в объявлении функции. Операции, выполняемые над ссылочным параметром, оказывают влияние на аргумент, используемый при вызове функции, а не на сам ссылочный параметр.

Чтобы лучше понять механизм действия ссылочных параметров, рассмотрим для начала простой пример. В следующей программе функция f() принимает один ссылочный параметр типа int.

// Задание 8.1_3.cpp: определяет точку входа для консольного приложения.

// Использование ссылочного параметра.

#include "stdafx.h"

#include <iostream>

using namespace std;

void f(int &i);    // Здесь i объявляется как ссылочный параметр.

int main()

{

setlocale(LC_ALL, "Russian");

int val = 1;

cout << "Старое значение переменной val: " << val << "\n";

f(val);            // Передаем адрес переменной val функции f().

cout << "Новое значение переменной val: " << val << "\n";

return 0;

}

void f(int &i)

{

i = 10;            // Модификация аргумента, заданного при вызове.

}

Дата: 2019-05-29, просмотров: 165.