Как я могу прочитать это сложное объявление в C?

Возможный дубликат:
в чем смысл этой части кода? void (* signal (int sig, void (* func) (int))) (int);

У меня есть сложное объявление, которое было взято из заголовочного файла signal.h, а ниже - объявление.

  void (*signal(int sig, void (*func)(int)))(int);

Теперь, как его разобрать? Как

сигнал - это функция, использующая два аргумента sig типа int и 'func, который является указателем на функцию, принимающую int в качестве аргумента и возвращающую тип void; он возвращает указатель на функцию, принимающую int как аргумент и возвращающую void.

Это нормально, или сигнал является указателем на функцию?

Ответ 1

Начните с самого левого идентификатора и проведите свой путь, вспомнив, что [] и () связывают до *, поэтому *a[] - это массив указателей, (*a)[] - указатель на массив, *f() - это функция, возвращающая указатель, а (*f)() - указатель на функцию:

       signal                                     -- signal
       signal(                          )         -- is a function
       signal(    sig,                  )         -- with a parameter named sig
       signal(int sig,                  )         --   of type int
       signal(int sig,        func      )         -- and a parameter named func
       signal(int sig,      (*func)     )         --   which is a pointer
       signal(int sig,      (*func)(   ))         --   to a function
       signal(int sig,      (*func)(int))         --     taking an int parameter
       signal(int sig, void (*func)(int))         --     and returning void
      *signal(int sig, void (*func)(int))         -- returning a pointer
     (*signal(int sig, void (*func)(int)))(   )   -- to a function
     (*signal(int sig, void (*func)(int)))(int)   --   taking an int parameter
void (*signal(int sig, void (*func)(int)))(int);  --   and returning void

signal связывает функцию обработчика сигнала func с сигналом sig и возвращает указатель на функцию старого обработчика сигнала:

void new_interrupt_handler(int sig)
{
  ... // do something interesting with interrupt signal
}

int main(void)
{
  void (*old_interrupt_handler)(int);
  ...
  /**
   * Set up our new interrupt handler
   */
  old_interrupt_handler = signal(SIGINT, new_interrupt_handler);
  ...
  /**
   * Restore original interrupt handler
   */
  signal(SIGINT, old_interrupt_handler);
  ...
}

Ответ 2

Используя cdecl.org, вы получите

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

для ввода

void (*signal(int, void(*)(int)))(int)

Это означает, что signal является функцией. Результатом вызова signal является указатель на функцию void f(int).

Объяснение: вызов signal() устанавливает новый обработчик сигналов и возвращает старый обработчик сигнала (поэтому вы можете восстановить его позже, если хотите).

Ответ 3

signal - это функция, которая принимает два параметра и возвращает указатель на функцию, которая принимает параметр int в качестве параметра и возвращает void.

Два параметра, которые signal принимает, являются int и указателем на функцию, которая принимает int в качестве параметра и возвращает void.

И да, вы получили описание и общую идею.

Ответ 4

Нет, это правильно. сигнал принимает 2 аргумента, int и указатель на функцию и возвращает указатель на функцию (с той же сигнатурой, что и аргумент func.)

Он похож на (imo) более читаемым:

typedef void (*sig_func)(int);
sig_func signal(int sig, sig_func func);

Ответ 5

void (*signal(int, void (*)(int)))(int);  

       signal(                  )         // signal is a function
              int, void (*)(int)          // the parameter types of the function:
                                          //    an int and a function pointer (take int, return void)
void (*                          )(int);  // the return type of the function:
                                          //    a function pointer (take int, return void)

//Отправляем ссылку на ответ Джона.