ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 23.06.2021
Просмотров: 1694
Скачиваний: 3

61
13. Подставляемые (inline) функции
Некоторые функции в СИ++ можно определить с использованием служебного
слова inline. Такая функция называется подставляемой или встраиваемой.
Например:
inline float Line(float x1,float y1,float x2=0, float y2=0)
{return sqrt(pow(x1-x2)+pow(y1-y2,2));}//функция возвращает расстояние от
точки с координатами(x1,y1)(по умолчанию центр координат) до точки с координатами
(x2,y2).
Обрабатывая каждый вызов подставляемой функции, компилятор пытается
подставить в текст программы код операторов ее тела. Спецификатор inline определяет
для функции так называемое внутреннее связывание, которое заключается в том, что
компилятор вместо вызова функции подставляет команды ее кода. При этом может
увеличиваться размер программы, но исключаются затраты на передачу управления к
вызываемой функции и возврата из нее. Подставляемые функции используют, если
тело функции состоит из нескольких операторов.
Подставляемыми не могут быть:
-
рекурсивные функции;
-
функции, у которых вызов размещается до ее определения;
-
функции, которые вызываются более одного раза в выражении;
-
функции, содержащие циклы, переключатели и операторы переходов;
-
функции, которые имеют слишком большой размер, чтобы сделать
подстановку.

62
14. Функции с переменным числом параметров
В СИ++ допустимы функции, у которых при компиляции не фиксируется число
параметров, и , кроме того может быть неизвестен тип этих параметров. Количество и
тип параметров становится известным только в момент вызова, когда явно задан список
фактических параметров. Каждая функция с переменным числом параметров должна
иметь хотя бы один обязательный параметр. Определение функции с переменным
числом параметров:
тип имя (явные параметры,. . . )
{тело функции }
После списка обязательных параметров ставится запятая, а затем многоточие,
которое показывает, что дальнейший контроль соответствия количества и типов
параметров при обработке вызова функции производить не нужно. Сложность
заключается в определении начала и конца списка параметров, поэтому каждая
функция с переменным числом параметров должна иметь механизм определения
количества и типов параметров. Существует два подхода:
1)
известно количество параметров, которое передается как
обязательный параметр;
2)
известен признак конца списка параметров;
Пример1
Найти среднее арифметическое последовательности чисел
//известен признак конца списка параметров
#include<iostream.h>
float sum(int k, . . .)
{
int *p=&k;//настроили указатель на параметр k
int s=0;
for(;k!=0;k--)
s+=*(++p);
return s/k;
}
void main()
{
cout<<”\n4+6=”<<sum(2,4,6);//находит среднее арифметическое 4+6
cout<<”\n1+2++3+4=”<<sum(4,1,2,3,4);//находит среднее арифметическое
1+2+3+4
}
Для доступа к списку параметров используется указатель *p типа int. Он
устанавливается на начало списка параметров в памяти, а затем перемещается по
адресам фактических параметров (++p).
Пример 2.
//известен признак конца списка параметров
#include<iostream.h>
int sum(int k, . . .)
{
int *p=&k;//настроили указатель на параметр k
int s=*p;//значение первого параметра присвоили s
for(int i=1;p!=0;i++)//пока нет конца списка
s+=*(++p);
return s/(i-1);

63
}
void main()
{
cout<<”\n4+6=”<<sum(4,6,0);//находит среднее арифметическое 4+6
cout<<”\n1+2++3+4=”<<sum(1,2,3,4,0);//находит среднее арифметическое
1+2+3+4
}

64
15. Перегрузка функций
Цель перегрузки состоит в том, чтобы функция с одним именем по-разному
выполнялась и возвращала разные значения при обращении к ней с различными типами
и различным числом фактических параметров. Для обеспечения перегрузки
необходимо для каждой перегруженной функции определить возвращаемые значения и
передаваемые параметры так, чтобы каждая перегруженная функция отличалась от
другой функции с тем же именем. Компилятор определяет какую функцию выбрать по
типу фактических параметров.
Пример.
#include<iostream.h>
#include <string.h>
int max(int a,int b)
{
if(a>b)return a;
else return b;
}
float max(float a,float b)
{
if(a>b)return a;
else return b;
}
char*max(char*a,char*b)
{
if(strcmp(a,b)>0) return a;
else return b;
}
void main()
{
int a1,b1;
float a2, b2;
char s1[20];
char s2[20];
cout<<"\nfor int:\n";
cout<<"a=?";cin>>a1;
cout<<"b=?";cin>>b1;
cout<<"\nMAX="<<max(a1,b1)<<"\n";
cout<<"\nfor float:\n";
cout<<"a=?";cin>>a2;
cout<<"b=?";cin>>b2;
cout<<"\nMAX="<<max(a2,b2)<<"\n";
cout<<"\nfor char*:\n";
cout<<"a=?";cin>>s1;
cout<<"b=?";cin>>s2;
cout<<"\nMAX="<<max(s1,s2)<<"\n";
}
Правила описания перегруженных функций:
1)
Перегруженные функции должны находиться в одной области видимости.
2)
Перегруженные функции могут иметь параметры по умолчанию, при этом
значения одного и того же параметра в разных функциях должны совпадать. В

65
разных вариантах перегруженных функций может быть разное количество
умалчиваемых параметров.
3)
Функции не могут быть перегружены, если описание их параметров отличается
только модификатором const или наличием ссылки.
Например, функции int&f1(int&,const int&){. . . } и int f1(int,int){. . . } – не являются
перегруженными, т. к. компилятор не сможет узнать какая из функций вызывается:
нет синтаксических отличий между вызовом функции, которая передает параметр по
значению и функции, которая передает параметр по ссылке.