Учись программированию на C++ Builder бесплатно!
  • Главная
  • Передача параметров в функции по значению и по ссылке
Передача параметров в функции по значению и по ссылке

Список параметров, передаваемый в функции, состоит из имен параметров и указаний на их тип. Например, в заголовке:

double FSum(double X1, double X2, int A)

указано три параметра X1, X2, А и определены их типы. Вызов такой процедуры может иметь вид:

Pr(Y, X2, 5);

Принцип работы

Это только один из способов передачи параметров в процедуру, называемый передачей по значению. Работает он так. В момент вызова функции в памяти создаются временные переменные с именами X1, X2, А, и в них копируются значения аргументов Y, X2 и константы 5. На этом связь между аргументами и переменными X1, X2, А разрывается. Можно изменять внутри процедуры значения X1, X2 и А, но это никак не отразится на значениях аргументов. Аргументы при этом надежно защищены от непреднамеренного изменения своих значений вызванной функцией. Это предотвращает случайные побочные эффекты, которые так сильно мешают иногда созданию корректного и надежного программного обеспечения.

Недостатки

  1. Затраты времени на копирование значений и затраты памяти для хранения копии. Если речь идет о какой-то переменной простого типа, это, конечно, не существенно. Но если, например, аргумент - массив из тысяч элементов, то соображения затрат времени и памяти могут стать существенными.
  2. Невозможность из функций изменять значения некоторых аргументов, что во многих случаях очень желательно.

Вызов по ссылке

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

  • с помощью ссылочных параметров;
  • с помощью указателей.

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

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

Примеры объявления

int &count
int & count
int& count

В списке параметров заголовка функции могут читаться как «count является ссылкой на int». В вызове такой функции достаточно указать имя переменной и она будет передана по ссылке. Реально в функцию передается не сама переменная, а ее адрес, полученный операцией адресации (&). Тогда упоминание в теле вызываемой функции переменной по имени ее параметра в действительности является обращением к исходной переменной в вызывающей функции и эта исходная переменная может быть изменена непосредственно вызываемой функцией.

Пример

void square(int&); // Прототип функции вычисления квадрата
void square(int &a) //Заголовок функции
{
	a *= a; // Изменение значения параметра
}

Вызываться подобная функция может обычным способом передачей в нее имени аргумента:

int x1 = 2;
square(x1);

В результате подобного вызова переменная x1 получит значение 4.

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

Указатель

Альтернативной формой передачи параметра по ссылке является использование указателей. Тогда адрес переменной передается в функцию не операцией адресации (&), а операцией косвенной адресации (*). В списке параметров подобной функции перед именем переменной указывается символ "*", свидетельствуя о том, что передается не сама переменная, а указатель на нее. В теле функции тоже перед именем параметра ставится символ операции разыменования "*", чтобы получить доступ через указатель к значению переменной. А при вызове функции в нее в качестве аргумента должна передаваться не сама переменная, а ее адрес, получаемый с помощью операции адресации &.

Пример

void square(int *); // Прототип функции вычисления квадрата
void square(int *а) //Заголовок функции
{
	*а *= *а; // Изменение значения параметра
}

Вызов подобной функции осуществляется следующим образом:

int x1 = 2;
square(&x1);

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