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

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

Имя функции (без параметров и без типа результата) является указателем-константой. Значением этого указателя является адрес размещения операторов функции в оперативной памяти. Это значение адреса можно присвоить другому указателю-переменной на функцию с тем же типом результата и с той же сигнатурой параметров. И затем этот новый указатель можно применять для вызова функции.

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

Определение указателя на функцию:

< тип_функции> (* имя указателя ) ( спецификация_параметров) =

< имя инициирующей функции>;

  • при определении спецификации параметров достаточно перечислить через запятую типы параметров, имена параметров можно опустить;

  • тип_функции – это тип результата, возвращаемого функцией;

  • тип_функции и спецификация_параметров в определении указателя должны совпадать с соответствующими типами и сигнатурами тех функций, адреса которых предполагается присваивать определяемому указателю, например, с помощью оператора присваивания;

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

Например:

int * ( * fptr ) ( char * , int );

int (*ptr) (char*);

- определения двух указателей:

fptrуказатель на функции с параметрами типа указателя на char и типа int, которые возвращают в качестве результата указатель на int;

ptr - указатель на функции с параметрами типа указателя на char, которые возвращают значение типа int.

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

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

Эквивалентные вызовы функции с помощью указателя на эту функцию:

имя указателя (список фактических параметров);

( * Имя указателя) (список фактических параметров);

Рассмотрим, как можно использовать указатель на функцию.

Определить и вызвать функцию вычисления длины строки - количества символов в строке до байтового нуля, строка – параметр функции. Вызов функции производить, используя указатель на функцию.

//Определение функции:

int len ( char * e)

{ int m=0;

while(e[m++] ) ;

return m-1 ;

}

void main ()

{ int (*ptr) (char*);

// объявлен неинициализированный указатель на функцию

ptr = len ;

// указателю присвоено значение – имя функции len;

char s [ ] =” rtgcerygw”;

//объявлен символьный массив, инициализированный строкой;

int n;

n = (* ptr) ( s);

//вызов функции с помощью указателя;

// эквивалентные вызовы: n = ptr (s) и n= len(s);

}

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

Пример вызова функций через указатель:

#include <iostream.h>

int add ( int n , int m ) { return ( n+m) ;}

int div ( int n , int m ) { return ( n / m) ;}

int mult ( int n , int m ) { return ( n * m) ;}

int subt ( int n , int m ) { return ( n - m) ;}

void main ( )

{ int ( * ptr) ( int , int ) ; // объявлен указатель на функцию;

int a, b ; char c;

cout<<”Введите два числа и символ арифметической операции: ”

cin >> a >> c >> b;

switch (c)

{ case ‘+’ : ptr = add ; break ;

case ‘-‘ : ptr = subt ; break;

case ‘ * ‘ : ptr = mult ; break;

case ‘ / ‘ : ptr = div ; break;

}

cout << a << c <<b<< “ =’’ << (*ptr) (a,b ) ; }