ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 23.06.2021

Просмотров: 1694

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

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 определяет 
для функции так называемое внутреннее связывание, которое заключается в том, что 
компилятор вместо вызова функции подставляет команды ее кода. При этом может 
увеличиваться размер программы, но исключаются затраты на передачу управления к 
вызываемой функции и возврата из нее. Подставляемые функции используют, если 
тело функции состоит из нескольких операторов. 

Подставляемыми не могут быть: 
-

рекурсивные функции; 

-

функции, у которых вызов размещается до ее определения; 

-

функции, которые вызываются более одного раза в выражении; 

-

функции, содержащие циклы, переключатели и операторы переходов; 

-

функции, которые имеют слишком большой размер, чтобы сделать 

подстановку. 


background image

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); 


background image

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 


background image

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)

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


background image

65 

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

3)

Функции не могут быть перегружены, если описание их параметров отличается 
только модификатором const или наличием ссылки. 

Например, функции int&f1(int&,const int&){. . . } и int f1(int,int){. . . } – не являются 

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