Выражение указателя функции
Итак, у меня есть следующее выражение:
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.
Тогда:
-
f( int(*a)(int,int) )
, если я вызываю f с аргументом a
;
-
*f( int(*a)(int,int) )
, а затем я разыгрываю результат;
-
(*f( int(*a)(int,int) )(int,int)
, а затем вызовите этот результат с помощью 2 int
в качестве аргумента
-
int (*f( int(*a)(int,int) )(int,int)
Я получаю int
So f
- это функция, принимающая аргумент a
в качестве аргумента и возвращающая указатель на функцию, которая принимает два int
в качестве аргумента и возвращает int
. Таким образом, возвращаемый тип f
совпадает с типом возвращаемого аргумента. Это могло быть проще:
using ftype = int(*)(int,int);
ftype f( ftype a);