Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

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




Ссылки

В С++ есть видоизмененная форма указателя – ссылка. Она может рассматриваться как указатель, который при употреблении всегда разименовывается. Фактически ссылка является еще одним именем или псевдонимом переменной. Объявляется при помощи унарного знака & (амперсанд) и при объявлении сразу же должна быть инициализирована. В общем, это выглядит как

тип &имя_ссылки = имя_переменной;

Например:

float x, &s=x;

Здесь s является ссылкой на переменную х типа float.

Ссылку можно инициализировать только один раз. Здесь уместно сравнить указатель и ссылку. Указатель – это переменная, которая может принимать значения адреса другой переменной определенного типа. Такие адреса можно присваивать несколько раз. Лишь бы это были адреса заданного типа переменных.

Ссылка тоже приобретает адрес, но это адрес конкретной переменной, и поменять его на адрес другой переменной нельзя!

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

По сравнению с использованием указателей удобство в том, что вызывающая функция избавляется от операции взятия адреса (&), а вызываемая – от операций * и à. О ссылках нужно знать следующее:

1. Ссылка не является самостоятельным типом и существует только после инициализации.

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 n,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_ Ø++;

}

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

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

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

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

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

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

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

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

void f(int k);

void f(const int k);

 

void f1(float x);

void f1(float y);

 

void f2(int x);

void f2(int&a);

 

Пример перегрузки для функций, используемых для вычисления объемов сферы (V=4/3πR3), параллелепипеда (V=xyz) и цилиндра (V=πR2h).

#include <stdio.h>

#include <math.h>

float v (float R);

float v (float x, float y, float z);

float v(float R, float H);

void main()

{

float v_sf,v_cil,v_par;

v_sf=v(2.5); //вычисление объема сферы для R=2.5

v_cil=v(3,4.5); // вычисление объема цилиндра для R=3, Н=4.5

v_par=v(2,4, Ø.7); //вычисление объема параллелепипеда

printf(“Объем сферы v_sf=%f\n

Объем цилиндра v_cil=%f\n

Объем параллелепипеда v_par=%f\n”, v_sf,v_cil,v_par);

}

float v(float R)

{

return 4*M_PI*pow(R,3)/3;

}

float v(float R, float H)

{

return M_PI*R*R*H;

}

float v(float x,float y,float z)

{

return x*y*z;

}




Поделиться с друзьями:


Дата добавления: 2015-06-27; Просмотров: 397; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.022 сек.