Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное пособие ОАиП.doc
Скачиваний:
11
Добавлен:
25.04.2019
Размер:
2.63 Mб
Скачать

Указатели на функции

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

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

тип_результата (*имя_указателя_на функцию)(список_типов_параметров);

В объявлении

int (*fun)(int, int *);

переменная fun является указателем на функцию с двумя параметрами: типа int и указателем на int. Сама функция должна возвращать значение типа int. Круглые скобки, содержащие имя указателя fun и признак указателя *, обязательны, иначе запись

int *fun (int, int *);

будет интерпретироваться как объявление функции fun возвращающей указатель на int. Это следует из того, что приоритет префиксного оператора * ниже, чем приоритет ().

Вызов функции возможен только после инициализации значения указателя fun и имеет вид:

(*fun)(i,&j);

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

fun( i,&j);

Ниже приведен пример использования указателя на функцию инициализированного адресом системной функции strcmp.

# include <stdio.h>

# include <string.h>

# define n 80

void check(char *, char , int ( cmp)(const char *,const char *)));

void main(void)

{ char s1[n],s2[n];

int (*p)(const char *,const char *);

p=strcmp; // p – адрес strcmp()

gets(s1); gets(s2);

check(s1,s2,p);

}

void check(char *a, char b, int ( cmp)(const char *,const char *)))

{ printf("\n строки ");

if (!(*cmp)(a,b)) printf("равны");

else printf("не равны");

}

При вызове check ей передается два указателя на символьные строки и один на функцию. Аналогично можно обращаться к check, используя и указатели на другие функции, если возвращаемый тип и передаваемые параметры, совпадают с рассмотренными выше. Выражение if(!(*cmp)(s1,s2)) можно заменить на if(!cmp(s1,s2)). Можно вызвать функцию check также следующим образом: check(s1,s2,strcmp). При этом не требуется использовать дополнительно указатель p.

Ниже приводятся примеры некоторых более сложных деклараций:

int (*ukz)[10]; - объявление указателя ukz на массив из 10 элементов int;

char (*(*fun))[]() - функция, возвращающая указатель на массив из функций, возвращающих значение типа char;

char (*(*m_ukz[5])())[10] - m_ukz[5] массив из указателей на функции, возвращающие указатели на массив из [10] элементов char.