Ответ 1
Общая процедура: найдите самый левый идентификатор и проведите свой путь. Отсутствие явной группировки с круглыми скобками, постфиксные операторы, такие как ()
и []
связывают перед унарными операторами, такими как *
; таким образом, все верно:
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, чтобы сделать это проще для чтения (и man-страница для signal
в Ubuntu linux делает именно это); однако, я думаю, что это важно, чтобы показать версию non-typedef'd, чтобы продемонстрировать, как работает синтаксис. Средство 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
на то, что, надеюсь, более наглядное.