Указатели на функции часто используют в качестве аргументов функций.
Однако предпочтительнее использовать вариант 1.
Указатель на функцию может инициализироваться при определении. При этом должны совпадать тип и сигнатура. Аналогично при присваивании значений указателю и при вызове функций с помощью указателей.
В определении указателя на функцию тип возвращаемого значения и сигнатура должны совпадать с соответствующими типами и сигнатурами тех функций, адреса которых предполагается присваивать вводимому указателю при инициализации или с помощью оператора присваивания.
Не путать с описанием
Имя функции без скобок и параметров выступает в роли указателя на эту функцию и его значением является адрес размещения функции в памяти.
Иногда под сигнатурой функции подразумевают список типов ее параметров.
Каждая функция характеризуется типом возвращаемого значения, именем и сигнатурой. Сигнатура определяется количеством, порядком следования и типами параметров.
Указатель на функцию определяется следующим образом:
тип_функции(*имя_указателя)(спецификация_ параметров);
Например: int(*f1Ptr)(char) определяет указатель f1Ptr на функцию с параметром типа char, возвращающую значение типа int. - это прототип функции с именем f1и параметром типасhar,возвращающей значение указателя типаint.
Это определение указателя f2Ptr на функцию с параметрами типа указатель на char и типа int, возвращающую значение типа указатель на char. Результат выполнения: В программе описан указатель ptr на функцию, и ему последовательно присваиваются адреса функций f1 и f2. Формат вызова функции: Значением имени_указателя служит адрес функции, а с помощью операции разыменования * обеспечивается обращение по адресу к этой функции. Ошибкой будет обращение Ибо () имеют более высокий приоритет, чем*. Вызывается функция по адресу, содержащемуся в указателе par следующим образом: Альтернативная форма вызова через указатель подобна нормальному вызову функции:int* f1(char);
char* (*f2Ptr)(char*, int);
#include <iostream>
using namespace std;
void f1 (void)
{cout << "выполняется f1()\n";}
void f2 (void)
{cout << "выполняется f2()\n";}
void main()
{ setlocale(LC_ALL,".1251");
void (*ptr)(void); // ptr - указатель на функцию
ptr=f2; // присваивается адрес f2()
(*ptr)(); // вызов f2 по адресу
ptr=f1; // присваивается адрес f1()
(*ptr)(); // вызов f1 по адресу
ptr(); // вызов эквивалентен (*ptr)();
}
выполняется f2()
выполняется f1()
выполняется f1()
(*имя_указателя)(спиcок_фактических_параметров);
*ptr();
char f1(char){…} //определение функции
char f2(int){…} //определение функции
void f3(float){…} //определение функции
int* f4(char*){…} //определение функции
char (*pt1)(int); //указатель на функцию
char (*pt2)(int); //указатель на функцию
void (*pt3)(float)=f3;
//инициализированный указатель на функцию
…
pt1=f1; //ош-несоотв сигнатур
pt2=f3; //ош-несоотв типов и сигнатур
pt1=f4; //ош-несоотв типов
pt1=f2; //ok!
pt2=pt1; //ok!
char c=(*pt1)(44);//ok!
c=(*pt2)(’\t’);// ош-несоотв сигнатур
Пример вызова функций с помощью указателей:
#include <iostream>
using namespace std;
//функции одного типа с одинаковыми //сигнатурами
int add (int n, int m) {return n+m;}
int divi(int n, int m) {return n/m;}
int mult(int n, int m) {return n*m;}
int subt(int n, int m) {return n-m;}
void main()
{ setlocale(LC_ALL,".1251");
int (*par)(int, int);
// указатель на функцию
int a=6, b=2;
char c='+';
while (c!='0')
{ cout<<"знак операции или 0?\n";
cin>>c;
switch (c)
{case '0': break;
case '+': par=add; break;
case '-': par=subt; break;
case '*': par=mult; break;
case '/': par=divi; break;
default : cout <<
"неверная операция" << endl;
c ='1'; break;
}
if ((c!='1')&&(c!='0'))
cout << a << c << b << "="<< (*par)(a,b)<< endl;
//вызов по адресу
}
}
(*par)(a,b); (1)
par(a,b); (2)