Синтаксис объявления (и использования) указателей на функции в C
(и C++
) является одним из самых загадочных аспектов языка для начинающих. Здесь я попытаюсь объяснить немного.
Сначала давайте рассмотрим указатели на «простые» типы (в качестве примера возьмем тип «int»). В этом случае объявление переменной типа является тривиальным: int N;
Кроме того, объявление указателя на int
также тривиально: int *pN;
Мы можем интерпретировать это второе объявление в терминах 'вычисления' оператора '*', что означает «получить объект, который находится по данному адресу». Итак, в int *pN
мы заявляем, что «объект, который находится по адресу« pN », является int
.
Для функций это не так просто! Возьмем случай функции, которая принимаетint
в качестве своего (единственного) аргумента и возвращает значение int
: int IFunc(int arg);
. Это также очень просто.
Но как мы можем объявить указатель на такую функцию? Мы не может просто применить ту же логику, что и для «простых» типов (с предшествующим оператором *
), например:
int *pIFunc(int arg);
Поскольку это объявит функция , которая принимает int
arg и возвращает указатель на int .
Итак, ранние разработчики языка C
должны были придуматьчто-то лучше - и совершенно недвусмысленно. Поэтому они решили использовать синтаксис, заключив раздел «* NAME» в круглые скобки, чтобы изолировать эту операцию «разыменования» от определения функции:со всем, что выглядит удаленно, как это: < typename > (*Name1)(...);
(когдаre - это любой допустимый тип C, например int
, void
, double
или даже «составные» типы, например int*
, и «...» внутри второго набора скобок можетбыть либо пустым, либо списком других типов), распознавать его как объявление указателя на функцию (или как разыменование указателя на функцию). Чтобы получить базовую функцию «подпись» (или вызов), просто удалите первый набор скобок и содержащийся *
. Итак, для:
(*ptr_fun1)(20)
вы можете прочитать:
ptr_fun1(20)
И для:
void (*ptr_fun1)(int);
вы можете увидеть, что ptr_fun
имеет следующую подпись:
void ptr_fun1(int);
Надеюсь, это прояснит ситуацию. Не стесняйтесь просить дальнейших разъяснений и / или объяснений.