Параметры функции

Основным способом обмена информацией между вызываемой и вызывающей функциями является механизм параметров. Существует два способа передачи параметров в функцию: по адресу и по значению.

При передаче по значению выполняются следующие действия:

- вычисляются значения выражений, стоящие на месте фактических параметров;

- в стеке выделяется память под формальные параметры функции;

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

Пример:

double square(double a, double b, double c)

{

//функция возвращает площадь треугольника, заданного длинами сторон а,b,c

double s, p=(a+b+c)/2;

return s=sqrt(p*(p-a)*(p-b)*(p-c));//формула Герона

}

1) double s1=square(2.5,2,1);

2) double a=2.5,b=2,c=1;

double s2=square(a,b,c);

3) double x1=1,y1=1,x2=3,y2=2,x3=3,y3=1;

double s3=square(sqrt(pow(x1-x2,2)+pow(y1-y2,2)),//расстояние между 1и2

sqrt(pow(x1-x3,2)+pow(y1-y3,2)), //расстояние между 1 и 3

sqrt(pow(x3-x2,2)+pow(y3-y2,2)));//расстояние между 2 и3

 

Стек

A 2.5
B
C
S  
P  

P и S – локальные переменные.

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

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

Пример.

void Change(int a,int b)//передача по значению

{int r=a;a=b;b=r;}

 

int x=1,y=5;

Change(x,y);

A
B
r  

cout<<”x=”<<x<<”y=”<<y;

выведется: x=1y=5

void Change(int *a,int *b)//передача по адресу

{int r=*a;*a=*b;*b=r;}

int x=1,y=5;

Change(&x,&y);

A &x
B &y
r  

cout<<”x=”<<x<<”y=”<<y;

выведется: x=5y=1

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

void Change(int &a,int &b)

{int r=a;a=b;b=r;}

int x=1,y=5;

Change(x,y);

A &x
B &y
r  

cout<<”x=”<<x<<”y=”<<y;

выведется: x=5y=1

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