Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кетков.doc
Скачиваний:
17
Добавлен:
27.09.2019
Размер:
2.22 Mб
Скачать

8.3. Параметры-ссылки

Формальный параметр в заголовке функции называют явным параметром-ссылкой, если перед его именем находится символ &. Например, функция swap2, осуществляющая перестановку местами значений двух переменных, должна получить в качестве параметров ссылки на эти переменные, т.е. их адреса:

void swap2(int &x,int &y) //явные параметры-ссылки

{ int tmp=x;

x=y; y=tmp;

}

Параметры-ссылки могут объявлены в заголовках функций и с помощью косвенных типов, предварительно описанных в конструкциях #define или deftype:

#define rint int&

//или

deftype int& rint;

...................

void swap2(rint x,rint y)

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

int x=2,y=3;

swap2(x,y);

По ссылке можно передавать не только имена переменных, но и имена указателей:

void swap3(int *&v1,int *&v2)

{ int *t=v2; v2=v1; v1=t; }

К этой функции можно обратиться следующим образом:

int i=10, j=20;

int *pi=&i, *pj=&j;

swap(pi,pj);

После этого обращения указатели pi и pj "смотрят" на новые значения (*pi=20, *pj=10), но сами переменные i и j сохранили свои прежние значения.

8.4. Параметры-константы

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

Оказывается, в этом скрывается некоторая уловка – если параметр объявлен как константная ссылка, то в качестве фактического аргумента в этом случае можно задавать не только имя переменной, но и выражение. Таким образом, параметр-ссылка уподобляется параметру-значению. Правда, при этом значение фактического аргумента не попадает в стек. Оно вычисляется и помещается в некоторую скрытую переменную в теле вызывающей функции. А вызываемой функции сообщается адрес этой скрытой переменной, что не меняет логику работы со ссылками. Но запись по этому адресу будет блокирована.

8.5. Параметры по умолчанию

В языке C++ допускается определение функций, у которых в заголовке указаны значения некоторых параметров:

double mid1(double x=0.5, double y=0.5)

{ return (x+y)/2.; }

К такой функции можно обратиться с одним (первым) аргументом или вообще без аргументов:

z=mid1(0.75); //результат равен 0.625=(0.75+0.5)/2.

p=mid1(); //результат равен 0.25=(0.5+0.5)/2.

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

double mid2(double x=0.5,double y)

В отличие от этого следующий заголовок считается правильным:

double mid3(double x,double y=0.5)

Обратите внимание на одну практическую деталь. Функция с параметрами по умолчанию работает правильно в двух случаях. Во-первых, если ее описание находится выше вызывающей функции и в заголовке функции содержится информация о параметрах по умолчанию. Во-вторых, если ее описание находится ниже и в заголовке функции отсутствуют сведения о параметрах по умолчанию, но они содержатся в прототипе. Одновременное упоминание значений по умолчанию и в заголовке функции, и в прототипе приводит к сообщению об ошибке как в системе BC 3.1, так и в ВСВ. Ниже приводится один из вариантов правильного оформления такой программы:

#include <iostream.h>

#include <conio.h>

double mid(double x=1.,double y=1.);

void main()

{ //double mid(double x,double y);

double x=0.4,y=0.2,z;

z=mid(x,y); cout<<"z="<<z<<endl;

z=mid(x); cout<<"z="<<z<<endl;

z=mid(); cout<<"z="<<z<<endl;

getch();

}

double mid(double x,double y)

{ return (x+y)/2.; }