Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Рацеев С.М. Программирование на языке Си.pdf
Скачиваний:
369
Добавлен:
23.03.2016
Размер:
1.65 Mб
Скачать

}

int main( )

{

int j = 1;

for (j = 1; j <= 10; j++) Print();

return 0;

}

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

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

Чтобы получить адрес той или иной функции, достаточно записать ее имя (которое и содержит ее адрес) без замыкающих скобок, то есть если F() – некоторая функция, то F – адрес данной функции. Например:

#include<stdio.h>

int Compare(int a, int b)

{

return a >= b;

}

int main( )

{

printf("%p\n", Compare); printf("%p\n", main); getch();

return 0;

}

175

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

Следующий пример иллюстрирует применение указателя на функцию.

#include<stdio.h>

 

int ShowMsg(char *msg)

 

{

 

return puts(msg);

 

}

 

int main( )

 

{

 

int (*pFunc)(char *);

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

pFunc = ShowMsg;

 

(*pFunc)("A message \n");

/* вызываем функцию через указатель */

return 0;

 

}

 

Приведем еще пример. Напишем функцию Count(), которая вычисляет количество больших или маленьких латинских букв в строке s. Пусть функции int Big(int c) и int Small(int c) соответственно определяют, является ли символ c большой или маленькой латинской буквой. Если в качестве параметра функции Count() передается адрес функции Big(), то она будет вычислять количество больших латинских букв в строке s. Если же данной функции передать адрес функции Small(), то она подсчитает количество маленьких латинских букв в строке s.

Взаголовке функция Count() имеет такой параметр: int (*flag)(int)

Это значит, что в качестве аргумента функция Count() может получить адрес абсолютно любой функции с тем условием, чтобы она возвращала результат целого типа, а в качестве параметра принимала тип int. Заметим, что вокруг *flag необходимы круглые скобки, чтобы соблюсти соответствующий приоритет операций. Круглые скобки имеют более высокий приоритет, нежели операция звездочка (*). Поэтому если записать

176

int *flag(int)

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

Функция, которая передается функции Count() в качестве параметра, вызывается в условии if:

if ((*flag)(s[i]))

Разыменовывание функции в данном случае необходимо, чтобы вызвать эту самую функцию.

#include<stdio.h> #define N 200

int Big(int);

/* прототип функции Big()

*/

int Small(int);

/* прототип функции Small()

*/

int Count(char *s, int (*)(int));

/* прототип функции Count() */

int Big(int c)

{

return (c >= 'A' && c <= 'Z');

}

int Small(int c)

{

return (c >= 'a' && c <= 'z');

}

int Count(char *s, int (*flag)(int))

{

int i, n; i = n = 0;

while (s[i] != '\0')

{

if ((*flag)(s[i])) n++;

i++;

}

177

return n;

}

int main( )

{

char s[N]; fgets(s, N, stdin);

printf("%d\n", Count(s, Big)); printf("%d\n", Count(s, Small)); return 0;

}

Приведем также пример использования массива указателей на функции. Определим три функции: Sum, Subtraction, Multiplication,

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

int (*f[3])(int, int) = {Sum, Subtraction, Multiplication};

После того как пользователь введет два целых числа (a и b) и номер арифметической операции над данными числами (0 – сумма, 1 – разность, 2 – произведение), приведенная ниже программа выведет на экран соответствующий результат (a+b, a-b или a*b).

#include<stdio.h>

int Sum(int, int);

int Subtraction(int, int); int Multiplication(int, int);

int Sum(int a, int b)

{

return a + b;

}

int Subtraction(int a, int b)

178