Вказівники на функції В мові С імя функції є константним вказівником на перший байт виконавчого коду функції. Це адреса оперативної памяті, яка відповідає точці входу даної функції. У разі виклику функції зчитується перша команда за цією адресою, а далі всі наступні команди. Адресу функції можна присвоїти вказівнику та використовувати його для звертання до функції. Оголошення вказівника на функцію тип_значення_функції (*імя_вказівника)(список типів_параметрів_функції) Операція – функція має вищий пріоритет ніж операція * - вказівник, тому конструкцію *імя_вказівника необхідно охопити дужками. Інакше дане оголошення було би прототипом функції, яка використовує відповідні параметри і повертає значення, яке є вказівником.
Приклад вказівника на функцію, що має два параметри і повертає вказівник на дані з типом char char* (*pfun) (char*, unsigned) Якщо оголошено дві функції char* FindWord (char* st, unsigned num); char* DelWord (char* sent, unsigned k); то коректними будуть присвоєння pfun = FindWord або pfun = &FindWord pfun = DelWord або pfun = & DelWord Вказівник можна застосовувати для звертання до функції. Після першого присвоєння, наступне звертання (*pfun)(str, 3); рівнозначне виклику FindWord (str, 3); Можна використовувати спрощене звертання pfun (str, 3), але краще конструкцію з розадресованим вказівником.
Приклад #include #include void print(char *s) { puts(s); } void main(void) { void (*efct)(char *s); efct=&print; /* efct=print */ (*efct)("Function Print!"); /* efct("Function Print!"); */ }
Покажчикам на функції можна присвоювати адреси стандартних бібліотечних функцій. #include #include #include void main(void) { double (*fn)(double); float y,x=1; fn=sin; y=fn(x); printf("sin(%g)==%g\n",x,y); fn=cos; y=fn(x); printf("cos(%g)==%g\n",x,y); }
Найчастіше вказівники на функції використовуються як формальні параметри у функціях вищого рівня. Це дає змогу створювати функції, які використовують інші функції без огляду на їх конкретні імена та внутрішнє наповнення. Приклад #include #include #include double fn(double (*pfn)(double ), double x) { double y=pfn(x); printf("y==%g\n", y); return y; }
double fun1 (double x) { return sin(x)*cos(x); } double fun2 (double x) { if (x>=0) return 3*cos(1.5*x) else return cos(x)*cos(x); } void main(void) { fn(sin,1); fn(fun1,1); fn(&fun2,1); }