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

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

4.1Понятие указателя на функцию и его объявление

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

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

Для объявления указателя на функцию используется заголовок функции, в котором вместо имени функции в круглых скобках пишется оператор * и имя указателя на функцию, например,

для функции добавления элемента в список, имеющей такой заголовок

void AddElSortList (void* &PtrArrPtr, void* NewP, int PosAddEl),

объявление указателя на такую функцию будет иметь вид:

void (*add_f)(void* &PtrArrPtr, void* NewP, int PosAddEl);

или

void (*add_f)(void* & , void*, int).

В данном примере создается указатель add_f на функцию, которая возвращает значение типа void и получает три параметра.

Круглые скобки вокруг (*add_f) обязательны, так как объявление без скобок будет иметь совершенно другой смысл. Такая строка

void *add_f(void* &, void*, int)

будет означать, что объявляется функция add_f, которая получает три параметра и возвращает нетипизированный указатель void*.

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

Конструкция

void (*add_f)(void* &, void*, int )

достаточно громоздкая. Поэтому удобнее, используя typedef, объявить тип для указателя на функцию, а затем использовать его в программе:

typedef

void (*Tptr_f)(void* & , void*, int);

Теперь объявление указателя на функцию будет иметь более простой вид:

Tptr_f add_func;

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

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

add_func = AddElSortList; // Формирование синонима (алиаса) имени функции

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

add_func (PtrDynArrPtr, NPtrElm, PosAdd); /* Вызов функции добавления но-

вого элемента в список через синоним (алиас)*/

или так:

(*add_func)(PtrDynArrPtr, NPtrElm, PosAdd); /* Вызов функции добавления

нового элемента в список через указатель*/

Первый вариант вызова функции короче, но второй вариант явно показывает, что функция вызывается через указатель.

В последующих разделах приводятся подробные иллюстрации использования переменных и параметров указателей на функции.

4.2Переменная-указатель на функцию как параметр другой функции

Для иллюстрации использования функции как параметра другой функции введем функцию – AсtionWithNumbers, которая получает два числа типа int и выполняет с ними определенное арифметическое действие, результат которого возвращает. Эта функция в качестве формального параметра использует параметр – указатель на функцию, в которой и происходит выполнение арифметической операции.

Функция AсtionWithNumbers имеет следующий вид:

int AсtionWithNumbers (int a, int b, int (*Func_Arifm) (int, int))

{

int rez ;

rez = Func_Arifm (a, b); /*вызов функции, переданной в качестве параметра*/

return rez;

} /* AсtionWithNumbers */

Функция APlusB имеет следующий вид:

int APlusB (int a, int b)

{

return a+b;

}

Ниже приводятся основные способы вызова функции APlusB, которая выполняет сложение двух чисел:

  1. Прямой вызов функции.

int n = APlusB (n1, n2);

  1. Фактическим параметром функции AсtionWithNumbers служит имя функции APlusB:

int n = AсtionWithNumbers (n1, n2, APlusB);

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

typedef

int (*TPFunc) (int, int); /*TPFunc – тип указателя на функцию*/

Теперь используем заранее объявленный тип для указателя на функцию в объявлении параметров функции.

int AсtionWithNumbers (int a, int b, TPFunc Func_Arifm )

{

int rez ;

rez = Func_Arifm (a, b); /*вызов функции, переданной в качестве параметра*/

return rez;

} /* AсtionWithNumbers */

Функция APlusB имеет следующий вид:

int APlusB (int a, int b)

{

return a+b;

}

Вызов функции APlusB, которая является аргументом функции AсtionWithNumbers:

int n = AсtionWithNumbers (n1, n2, APlusB);