Как работает синтаксис «Указатель на функцию» в C? - PullRequest
0 голосов
/ 12 октября 2019

Как (* ptr_fun1) (10) и ptr_fun1 (10) совпадают в приведенном ниже коде

Код:

#include<stdio.h>
void fun1(int a)
{
     printf("It is %d\n",a);
}
int main()
{
  void (*ptr_fun1)(int);
  ptr_fun1 = fun1;
/*
   ex-
        ptr_fun1    fun1    
        +----+      +-----+
        +1000+      +code +
        +----+      +-----+
         1234        1000
        fun1(10); <=> ptr_fun1(10); //how
*/
  printf("%d\n%d",ptr_fun1(10),(*ptr_fun1)(20));
  return 0;
}

выход

10
20

Может кто-нибудь объяснить, пожалуйста, как это работает.

1 Ответ

1 голос
/ 12 октября 2019

Синтаксис объявления (и использования) указателей на функции в CC++) является одним из самых загадочных аспектов языка для начинающих. Здесь я попытаюсь объяснить немного.

Сначала давайте рассмотрим указатели на «простые» типы (в качестве примера возьмем тип «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);

Надеюсь, это прояснит ситуацию. Не стесняйтесь просить дальнейших разъяснений и / или объяснений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...