Case 1
In the statement:
void (*signal(int signo, void (*func)(int)))(int);
The above is a declaration for a function named signal that has the following properties:
signal takes two parameters. The first parameter of signal is of type int and is named signo. The second parameter of signal is of type void(*)(int) and is named func. That is, func is a pointer to a function with one parameter of type int and return type of void.
signal has the return type void (*)(int). That is the return type of signal is a pointer to a function that takes one parameter of type int and has return type of void.
To make this more readable we can use the placeholder type auto and decltype in C++11(as this question was originally tagged C++ also) as shown below:
//more readable
auto signal(int signo, void (*func)(int)) -> void(*)(int);
Case 2
Now lets look at the second case:
typedef void Sigfunc(int); //Sigfunc is a typedef for the function type void (int)
Sigfunc *signal(int signo, Sigfunc *func);
SigFunc is a typedef for the function type void (int). Thus Sigfunc* is nothing but void (*)(int). And since in this case the return type is specified as Sigfunc*, the return type is the same as void (*)(int). Note that specifying the * is important here.
Case 3
Now lets look at case 3:
typedef void (*p_Sigfunc)(int); //p_Sigfunc is a typedef for void (*)(int)
p_Sigfunc signal(int signo, p_Sigfunc func);
//--------^------------------------------------>no need for explicitly writing "*" here
Here p_Sigfunc is a typedef for void (*)(int). Note in this case we don't need to the * because we already have void (*)(int) instead of void (int).
All of these function declarations are equivalent.
typedef int* int_pointer;,const int_pointeris notconst int*/int const*butint* const.Sigfuncis a funtion whileSigfunc*is a pointer to a function. Function types are very useful and readable but they are poorly communicated by educators.