Pers.narod.ru. Алгоритмы. Используем указатель на функцию |
Указатели на функции - один из ключевых для понимания Си моментов, который часто обходится стороной в книгах по языку. Между тем, структуры данных в сочетании с динамическими указателями на функции и образуют суть реализации того, что называют объектно-ориентированным программированием. В приведенном ниже простом примере указатель на функцию используется как элемент структуры, содержащей описание пункта меню.
#include <conio.h>
#include <stdlib.h>
typedef unsigned char byte;
typedef void (*FUN)(void);
//Указатель на функцию обработки
//пункта меню - указатель на объекты вида void Функция(void)
struct MENU { //например, опишем простейшее меню
int x,y; // Позиция на экране пункта меню
byte *str; // Строка текста меню
FUN sf; // Указатель на функцию
// обработки пункта
};
/* код функций обработки пункта меню */
void Exit () { exit (0); }
void Start () { }
/* Код функций вывода и поддержки меню */
void DrawMenu (MENU *m) {
gotoxy(m->x,m->y);
cprintf ("%s",m->str);
}
#define ITEMS 2
void main () {
MENU Menu[ITEMS]={
{ 1, 1, "Начать", Start },
{10, 1, "Выход", Exit }
};
clrscr ();
for (int i=0; i<ITEMS; i++)
DrawMenu (&Menu[i]);
Menu[0].sf(); /*Вызвали Start() косвенно, через указатель на функцию*/
}
В следующем примере указатель на функцию позволяет в процессе выполнения программы вызывать по нему разные подпрограммы.
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <alloc.h>
typedef char * (* function) (char *);
function sf;
char * f1 (char *s) {
return strlwr(s);
}
char * f2 (char *s) {
return strupr(s);
}
void main () {
sf=f1;
printf ("\nsf=%s",sf("Test"));
sf=f2;
printf ("\nsf=%s",sf("Test"));
}
В общем виде, для записи
int (*number_compare) ();
тип переменной number_compare - это указатель на функцию, которая вызвращает целое значение. Скобки вокруг *number_compare обязательны. Без них Си будет использовать свои правила порядка выполнения действий и интерпретирует строку, как описание функции, возвращающей указатель на элемент типа int.
С указателями на функцию следует использовать только операторы =, == и * (унарная операция косвенной адресации по указателю, а не умножение); все другие операции не определены.
|
|