Выражение указателя функции

Итак, у меня есть следующее выражение:

int (*f1(int(*a)(int, int))) (int, int);

и я пытаюсь понять это, но это сбивает с толку. Я понял, что "a" является указателем на функцию, которая принимает 2 аргумента (int, int). Тогда f1 представляется указателем на другую функцию, которая принимает 2 аргумента int. Но то, что меня смущает, - это то, как f1 относится к a.

Может кто-нибудь дать мне некоторые подсказки или правильно объяснить, что делает это выражение?

Ответ 1

Он объявляет f1 как функцию с единственным параметром с именем a. Оба типа параметра и типа возврата являются "указателем на функцию с двумя параметрами int, возвращающими int".


Вот как вы его разобрали:

// f1 is...
      f1
// ...a function...
      f1(                 )
// ...with a single parameter called `a`, which is...
      f1(     a           )
// ...a pointer to...
      f1(    *a           )
// (skip parentheses)
      f1(   (*a)          )
// ...a function...
      f1(   (*a)(        ))
// ...with two `int` parameters...
      f1(   (*a)(int, int))
// ...returning an `int`. The `f1` itself returns...
      f1(int(*a)(int, int))
// ...a pointer to...
     *f1(int(*a)(int, int))
// (skip parentheses)
    (*f1(int(*a)(int, int)))
// ...a function...
    (*f1(int(*a)(int, int))) (        )
// ...with two int parameters...
    (*f1(int(*a)(int, int))) (int, int)
// ...returning an `int`.
int (*f1(int(*a)(int, int))) (int, int)

Ответ 2

Это объявление функции f1, которая принимает параметр a - указатель на функцию, которая принимает 2 int в качестве аргумента и возвращает int - и возвращает указатель на функцию того же типа.

Прервать его с помощью typedef:

typedef int(*t)(int, int);

t f1(t a); //this is your declaration

Ответ 3

a - это имя параметра f1 only; когда вы удалите его, вы можете использовать https://cdecl.org/, чтобы расшифровать всю декларацию:

объявить функцию f1 как функцию (указатель на функцию (int, int), возвращающий int) возвращающий указатель на функцию (int, int), возвращающую int

So f1 - это функция. Он принимает указатель на функцию (называемый a) и возвращает указатель на функцию.

Оба эти указателя функций предназначены для функций, которые принимают два int и возвращают int.

Вот пример, чтобы увидеть все это в действии:

#include <iostream>

int passed(int x, int y) { std::cout << "passed\n"; return x * y; }
int returned(int x, int y) { std::cout << "returned\n"; return x + y; }

// a is redundant here, where we just declare f1:
int (*f1(int(*a)(int, int))) (int, int);

// but not here, where we define f1:
int (*f1(int(*a)(int, int))) (int, int)
{
    std::cout << "f1\n";
    int result_of_passed = a(10, 10);
    std::cout << result_of_passed << '\n';
    return returned;
}

int main()
{
    int x = f1(passed)(10, 10);
    std::cout << x << '\n';
}

Вывод:

f1
passed
100
returned
20

Ответ 4

Кончик в C должен читать объявление как бы выражение. Это знаменитая симметрия, которая делает C элегантным.

Как это прочитать? следуя правилам приоритета операторов:

  • *a: если я переменяю переменную a;
  • (*a)(int,int): а затем вызовите его двумя целыми числами:
  • int (*a)(int,int): тогда я получаю целое число;

So a - это указатель на функцию, берущую два параметра int и возвращающий int.

Тогда:

  1. f( int(*a)(int,int) ), если я вызываю f с аргументом a;
  2. *f( int(*a)(int,int) ), а затем я разыгрываю результат;
  3. (*f( int(*a)(int,int) )(int,int), а затем вызовите этот результат с помощью 2 int в качестве аргумента
  4. int (*f( int(*a)(int,int) )(int,int) Я получаю int

So f - это функция, принимающая аргумент a в качестве аргумента и возвращающая указатель на функцию, которая принимает два int в качестве аргумента и возвращает int. Таким образом, возвращаемый тип f совпадает с типом возвращаемого аргумента. Это могло быть проще:

using ftype = int(*)(int,int);
ftype f( ftype a);