Общая процедура: найдите самый левый идентификатор и проработайте свой выход.При отсутствии явной группировки с круглыми скобками постфиксные операторы, такие как ()
и []
, связываются с унарными операторами, такими как *
;таким образом, все верно:
T *x[N] -- x is an N-element array of pointer to T
T (*x)[N] -- x is a pointer to an N-element array of T
T *f() -- f is a function returning a pointer to T
T (*f)() -- f is a pointer to a function returning T
Применяя эти правила к объявлению, оно разбивается на
signal -- signal
signal( ) -- is a function
signal( signo, ) -- with a parameter named signo
signal(int signo, ) -- of type int
signal(int signo, func ) -- and a parameter named func
signal(int signo, *func ) -- of type pointer
signal(int signo, (*func)( )) -- to a function
signal(int signo, (*func)(int)) -- taking an int parameter
signal(int signo, void (*func)(int)) -- and returning void
*signal(int signo, void (*func)(int)) -- returning a pointer
(*signal(int signo, void (*func)(int)))( ) -- to a function
(*signal(int signo, void (*func)(int)))(int) -- taking an int parameter
void (*signal(int signo, void (*func)(int)))(int); -- and returning void
Короче говоря, signal
возвращает указатель на функцию, возвращающуюvoid
.signal
принимает два параметра: целое число и указатель на другую функцию, возвращающую void
.
Вы можете использовать typedefs, чтобы упростить чтение (и справочная страница для signal
в Ubuntu linux делает именно это);Тем не менее, я думаю, что полезно показать версию без определения типа, чтобы продемонстрировать, как именно работает синтаксис.Функция typedef замечательна, но вам действительно нужно понять, как работают базовые типы, чтобы эффективно ее использовать.
Функция signal
устанавливает обработчик сигнала;второй аргумент - это функция, которая должна быть выполнена, если получен сигнал.Указатель на текущий обработчик сигнала (если есть) возвращается.
Например, если вы хотите, чтобы ваша программа обрабатывала сигналы прерывания (например, от Ctrl-C):
static int g_interruptFlag = 0;
void interruptHandler(int sig)
{
g_interruptFlag = 1;
}
int main(void)
{
...
/**
* Install the interrupt handler, saving the previous interrupt handler
*/
void (*oldInterruptHandler)(int) = signal(SIGINT, interruptHandler);
while (!g_interruptFlag)
{
// do something interesting until someone hits Ctrl-C
}
/**
* Restore the previous interrupt handler (not necessary for this particular
* example, but there may be cases where you want to swap out signal handlers
* after handling a specific condition)
*/
signal(SIGINT, oldInterruptHandler);
return 0;
}
EDIT Я расширил пример кода для signal
к чему-то, что, надеюсь, более показательно.