Язык С++ для системного программирования. Имена-этикетки. Класс как область действия, страница 2

2.  Какие-либо операции осуществляются не над ссылками, а над объектами, на которые они ссылаются.

3.  Ссылка не может ссылаться на другую ссылку или на битовое поле.

4.  Не может быть массива ссылок.

5.  Не может быть указателей на ссылку, но может быть ссылка на указатель,например int *&rpi;//ссылка на указатель на int.

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

float f(const int &x, float a).

При попытке в процессе выполнения функции f( ) присвоить значение константе х компилятор сообщит об ошибке.

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

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

fukaz() - передача результатов с помощью указателей;

fssilka() - передача результатов с использованием ссылок.

С целью уменьшения объема программы рассмотрим случай обработки только одного одномерного массива x[1Ø].

#include <stdio.h>

#define Nx 1Ø

void vvod (float x[],int n,char q);

void fukaz(float x[], int n, float*sum_otr,int*kol_Ø, float*sum_pol);

void fssilka(float x[], int n, float &sum_otr, int &kol_Ø, float &sum_pol);

void main()

{

float x[Nx], s_p, s_o;

int k_nul;

vvod (x, Nx, 'x');

fukaz (x,Nx,&s_o,&k_nul,&s_p);

printf("s_0=%f k_nul=%i s_p=%f\n",s_o, k_nul, s_p); //Далее

следует вызов функции с передачей данных с помощью ссылок

fssilka(x,Nx,s_o,k_nul,s_p);

printf("s_o=%f k_nul=%i s_p=%f\n",s_o,k_nul,s_p); //Естественно, что результаты совпадают

}

void vvod(float x[],int n,char q)

{

for(int i=Ø; i<n;i++)

{printf("введите %c[%i]=\n",q,i);

scanf("%f",&x[i]);

}

return;

}

void fukaz(float x[],int ,float*sum_otr, int*kol_Ø, float*sum_pol)

{

*sum_otr=Ø;

*kol_Ø=Ø;

*sum_pol=Ø;

for(int i=Ø; i<n;i++)

if(x[i]<Ø)

*sum_otr+=x[i];

else

if(x[i]>Ø)

*sum_pol+=x[i];

else

*kol_Ø+=1;//(*kol_Ø)++

}

void fssilka (float x[],int n, float &sum_0 tr,int kol_Ø,float

&sum_pol)

{

sum_otr=kol_Ø=sum_pol=Ø

for(int i= Ø;i<n;i++)

if(x[i]<Ø)

sum_otr+=x[i];

else

if(x[i]> Ø)

sum_pol+=x[i];

else

kol_ Ø++;

}

16.5 Перегруженные функции

В С++ разрешено нескольким функциям иметь одинаковые символические имена (идентификаторы). Однако такие функции должны отличаться между собой или количеством параметров, или их типами, или порядком следования типов. Компилятор перед именем функции ставит несколько символов. Получается т.н. декорированное имя. Например, для функции с прототипом:

void f(int x) декорированное имя @f$qi. Для void f (char x) - @f$qc.

Для void f(char*x) - @f$qpc.

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

· если они отличаются только типом возвращаемого результата;

· если отличаются только применением модификаторов const, volative;

· если отличие одного типа параметров от другого заключается в наличии в одном из них ссылки.

Ниже следуют примеры пар функций, которые не могут быть перегружены.

void f(int k);

void f(const int k);

void f1(float x);