Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЯВУ - методичка1.doc
Скачиваний:
8
Добавлен:
08.11.2019
Размер:
683.52 Кб
Скачать

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

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

тип (* имя) (список типов); , где

тип – спецификатор типа возвращаемого функций значения;

имя – идентификатор указателя-переменной на функцию;

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

Например, рассмотрим определение объекта fun:

int (*fun ) ( int );

1 ) объект с этим именем есть

2 ) указатель

3 ) на функцию

4 ) с одним аргументом типа int

5 ) и возвращаемое значение типа int.

Скобки (*fun) необходимы, так как в описании скобки ( ) связываются с именем раньше, чем символ ‘*’. Объявление вида int *fun ( ); означает функцию fun, возвращающую указатель на объект целого типа. Точно так же как указание имени массива без [ ] означает адрес его первого байта, указание имени функции без ( ) задаёт адрес её начала.

Пример. Демонстрация использования указателя-переменной на функцию (funprt), которой можно присваивать ссылки на разные функции.

Программа:

#include <stdio.h>

#include <conio.h> /* для функций clrscr и getch */

int difference (int, int); /* прототипы функций */

int sum (int, int);

void main ()

{ /* int (*funptr) (int, int); указатель-переменная на функцию с 2-мя аргументами */

int (*funptr) (); /* указатель-переменная без аргументов */

int var1=2, var2=5, ret; /* рабочие переменные */

clrscr(); /* очистка экрана */

funptr = difference; /* указатель получает адрес 1-й функции */

ret = funptr(var1, var2); /* результат функции по указателю */

puts (“Результаты программы:”);

printf (“ret = %d\n”, ret); /* вывод результата */

funptr = sum; /* указатель получает адрес 2-й функции */

ret = funptr(var1, var2); /* результат функции по указателю */

printf (“ret = %d\n”, ret); /* вывод результата */

getch(); /* задержка экрана результатов */

}

int difference (int a, int b) /* описание функции вычитания */

{return (a – b);}

int sum (int a, int b) /* описание функции сложения */

{return (a+b);}

Результаты программы:

ret = –3

ret = 7

Использование указателя на функцию как аргумента

Многие функции (в том числе библиотечные) в качестве аргумента используют указатель на функцию. Это позволяет разрабатывать универсальные функции.

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

Пример. Демонстрация использования функции алгоритма быстрой сортировки с прототипом в <stdlib.h>:

void qsort (void base, int nelem, int width, int (*fcmp)(const void *elem1, const void *elem2));

  • сортирует nelem элементов (объектов) размером width каждый, размещенных в памяти, начиная с указателя base, в соответствии с функцией сравнения (библиотечной или пользователя), задаваемой переменной-указателем fcmp на функцию сравнения с двумя аргументами, которая возвращает значение:

< 0, если *elem1 < *elem2,

= 0, если *elem1 == *elem2,

> 0, если *elem1 > *elem2.

Программа:

#include <stdio.h>

#include <stdlib.h> /* для функции qsort() */

#include <string.h> /* для функции strcmp() */

#include <conio.h>

int compare (const void *a, const void *b); /* прототип функции */

void main (void) /* главная функция */

{ int i;

char list [5][4] = {“cat”, “car”, “cab”, “cap”,”can” }; /* массив обьектов сортировки */

clrscr (); /* очистка экрана */

qsort (list, 5, sizeof(list[0]), compare); /* вызов функции */

puts (“Результаты алгоритма быстрой сортировки:”);

for (i=0; i<5; i++) /* цикл по элементам (строкам) */

printf(“%s\n”, list[i]); /* вывод отсортированных строк */

getch(); /* задержка экрана результатов */

} /* конец функции main() */

int compare (const void *a, const void *b) /* функция сравнения */

{

return (strcmp(a,b)); /* возврат результата сравнения */

}

Результаты программы:

Результаты алгоритма быстрой сортировки:

cab

can

cap

car

cat