Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Передача имен функций в качестве параметров




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

void f(int a) { /* Тело функции */} // Определение функции

void (*pf) (int); // указатель на функцию

...

pf = &f; // указателю присваивается адрес функции

pf(10); // функция f вызывается через указатель pf

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

 

# include <iostream.h>

typedef void (*pf) (int); // Описание типа PF как указателя на функцию

// Функция f1 получает в качестве параметра указатель типа PF

void f1(PF pf) {

pf(5); // Вызов функции, переданной через указатель

}

void f(int i) { cout << i; }

int main () {

f1(f);

return 0;

}

Параметры со значениями по умолчанию

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

int f (int a, int b=0);

void f1 (int, int = 0, char*=0);

...

f(100);

f(a,1);

...

f1(a); f1(a,10); f1(a, 10, "Ivan");

Перегрузка функций

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

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

Пример. Функции, возвращающие наибольшее из двух значений:

int max (int, int);

char * max (char*, char*);

int max (int, char*);

int max (char*, int);

// для параметров-строк вычисляется длина

void f(int a, int b, char *c, char *d) {

cout<<max(a,b)<<max(c,d)<<max(a,c)<<max(c,b);

}

При вызове функции max компилятор выбирает соответствующий типу фактических параметров вариант функции. Если точного соответствия не найдено, выполняются продвижения порядковых типов в соответствии с общими правилами, например bool и char в int, float в double и т.п. Далее выполняются стандартные преобразования типов, например int в double или указателей в void*. Следующим шагом является выполнение преобразований типа, заданных пользователем, а также поиск соответствий за счет переменного числа аргументов функций. Если соответствие на одном и том же этапе может быть получено более чем одним способом, вызов считается неоднозначным и выдается сообщение об ошибке.

Неоднозначность может проявиться:

- при преобразовании типа;

- при использовании параметров-ссылок;

- при использовании аргументов по умолчанию.

Пример. Неоднозначность при преобразовании типа:

# include <iostream.h>

float f(float i) {

cout << "fuction float f(float i)"<<endl; // endl переводит строку при использовании // потоков ввода-вывода

return i;

}

doudle f(double i) {

cout << "fuction double f(double i)"<<endl;

return i*2;

}

int main () {

float x = 10.09;

double y = 10.09;

cout << f(x) << endl; // вызывается f(float)

cout << f(y) << endl; // вызывается f(double)

/* cout << f(10) << endl; − неоднозначность: как преобразовать 10: во float или double? */

return 0;

}

Для устранения этой неоднозначности требуется явное приведение типа для константы 10.

Пример неоднозначности при использовании параметров-ссылок: если одна из перегружаемых функций объявлена как Int f(int a, int b), а другая int f(int a, int &b), то компилятор не сможет узнать, какая из этих функций вызывается. так как нет синтаксических различий между вызовом функции, которая получает параметр по значению, и вызовом функции, которая получает параметр по ссылке.

Пример. Неоднозначность при использовании аргументов по умолчанию:

# nclude <iostream.h>

int f(int a) { return a;}

int f(int a, int b =1) {return a*b;}

int main () {

cout << f(10,2); // вызывается f(int, int)

// cout << f(10); - неоднозначность: что вызывается - f(int) или f(int, int)?

return 0;

}





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


Дата добавления: 2016-10-06; Мы поможем в написании ваших работ!; просмотров: 760 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Жизнь - это то, что с тобой происходит, пока ты строишь планы. © Джон Леннон
==> читать все изречения...

2269 - | 2040 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.008 с.