Подтвердить что ты не робот

Синтаксис C для функций, возвращающих указатели функций

Рассмотрим следующие typedefs:

typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);

f2 - это функция, которая возвращает указатель на функцию. То же самое с f3, но тип функции, указатель на который f3 возвращает, равен f2. Как определить f3 без typedefs? Я знаю, что typedefs являются более понятным и понятным способом определения f3. Однако мое намерение здесь состоит в том, чтобы лучше понять синтаксис Си.

4b9b3361

Ответ 1

Начните с объявления для f1:

int (*f1)(float);

Вы хотите, чтобы f2 был указателем на функцию, возвращающую f1, поэтому замените f1 в объявлении выше декларацией для f2:

int (*      f1     )(float);
            |
      +-----+-----+
      |           |
      v           v
int (*(*f2)(double))(float);

Декларация читается как

        f2                   -- f2
       *f2                   -- is a pointer
      (*f2)(      )          -- to a function
      (*f2)(double)          --   taking a double parameter
     *(*f2)(double)          --   returning a pointer
    (*(*f2)(double))(     )  --   to a function
    (*(*f2)(double))(float)  --     taking a float parameter
int (*(*f2)(double))(float)  --     returning int

Вы повторяете процесс для f3:

int (*(*    f2    )(double))(float);
            |
        +---+----+
        |        |
        v        v
int (*(*(*f3)(int))(double))(float);

который читается как

          f3                           -- f3
         *f3                           -- is a pointer
        (*f3)(   )                     -- to a function
        (*f3)(int)                     --   taking an int parameter
       *(*f3)(int)                     --   returning a pointer
      (*(*f3)(int))(      )            --   to a function
      (*(*f3)(int))(double)            --     taking a double parameter
     *(*(*f3)(int))(double)            --     returning a pointer
    (*(*(*f3)(int))(double))(     )    --     to a function
    (*(*(*f3)(int))(double))(float)    --       taking a float parameter
int (*(*(*f3)(int))(double))(float);   --       returning int

Ответ 2

В С++ чудо шаблонов может сделать это немного легче.

#include <type_traits>

std::add_pointer<
    std::add_pointer<
        std::add_pointer<
            int(float)
        >::type(double)
    >::type(int)
>::type wow;

Ответ 3

То же, что и с typedef, вы вместо определения своей функции вместо своего имени указываете.

Вот как выглядел бы f2:

typedef int (*(*f2)(double))(float);

Вы можете сделать f3 как упражнение, так как я предполагаю, что это домашнее задание;)

Ответ 4

Просто не надо. Это можно сделать, но это будет очень запутанно. Typedef там, чтобы облегчить запись и чтение этого кода.

Функция f, которая не принимает аргументов и возвращает указатель на функцию int (*)(float), вероятно, будет чем-то вроде (untested):

int (*f())(float);

Тогда для остальных вам просто нужно добавить скобки, пока она не будет выглядеть как lisp.

Ответ 5

Изучите правое правое правило:

Правило "право-левое" является полностью регулярным правилом для расшифровки C деклараций. Он также может быть полезен при их создании.

Ответ 6

Используйте std::function:

typedef std::function<int(float)> f1;
typedef std::function<f1(double)> f2;
typedef std::function<f2(int)>    f3;

или

typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3;