Во-первых, мой обычный метод определения сложных типов. Начните с идентификатора, а затем добавьте к остальным один шаг за раз:
f -- f
f[N] -- is an N-element array
*f[N] -- of pointers
(*f[N])() -- to functions
T (*f[N])() -- returning T
Для массива указателей на функции, принимающих двойной параметр и возвращающих двойное значение, это будет
double (*f[N])(double);
Однако помните, что выражения массива типа «распад» из типа «массив N-элементов из T» в «указатель на T» в большинстве контекстов. Когда вы передаете выражение массива в качестве аргумента функции, функция фактически получает указатель. Таким образом, вместо получения объекта типа «N-элементный массив указателей на функцию, возвращающую double», ваша функция получит объект типа «указатель на указатель на функцию, возвращающую double», или
double (**f)(double)
То есть ваше определение функции будет выглядеть примерно так:
void func(double (**f)(double))
{
int i;
...
for (i = 0; f[i] != NULL; i++)
{
double x = (*f[i])((double) i);
}
}
И вызывающий абонент будет выглядеть примерно так:
double a(double x) {...}
double b(double x) {...}
double c(double x) {...}
void foo(void)
{
double (*list[])(double) = {a, b, c, NULL};
func(list);
}
Если вы хотите вместо этого использовать typedefs, вы можете использовать что-то вроде этого:
typedef double Dblfunc(double); // typedef for function type
typedef Dblfunc *Dblfuncptr; // typedef for function pointer type
void func(Dblfuncptr *f)
{
int i;
for (i = 0; f[i] != NULL; i++)
{
double x = (*f[i])((double) i);
...
}
}
...
void foo(void)
{
Dblfuncptr list[] = {a, b, c, NULL}; // EDIT: fixed type
func(list);
}
Использование typedefs делает массив и параметр функции более похожими на обычные типы. Лично я предпочитаю использовать «необработанные» типы, поскольку это явно показывает, что я имею дело с указателями на функции, и показывает, что представляют собой возвращаемый тип и типы параметров.