Once you start mixing pointers to functions in your C declarations you’ll notice that things can get complex. For example, what does the following declaration represent:
float * (* (*ptr)(int))(double **,char c)
What about this one:
unsigned **( * (*ptr)  ) (char const *,int *)
One tool you can use to help you with those complex declarations is called cdecl.org. You can type the C declaration and the tool will translate it into English to you, and vice-versa.
This tool also comes with GCC, so you can use it via the command line as well.
And here are is what the above declarations stand for:
First one: ptr is a pointer to a function that takes as parameter an int, and returns a pointer to a function that takes as parameters a pointer to pointer to double and a char, and returns a pointer to float.
Second one: ptr is a pointer to an array of five pointers to functions that take as parameters a constant pointer to char and a pointer to int, returning a pointer to a pointer of unsigned int.
There was a question about those declarations a while ago on Programmers.StackExchange.com.