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

Использование указателя для обеспечения вызова по ссылке

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

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

void swap(int *х, int *у)

{

 int temp;

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

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

 *у = temp; // Помещаем значение, которое раньше хранилось по адресу х, в адрес у.

}

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

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

#include

using namespace std;

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

void swap(int *х, int *у);

int main()

{

 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 *y)

{

 int temp;

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

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

 *у = temp; // Помещаем значение, которое раньше хранилось по адресу х, в адрес у.

}

Результаты выполнения этой программы таковы.

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

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

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

Ссылочные параметры

Ссылочный параметр автоматически получает адрес соответствующего аргумента.

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги