How do I interpret complex declarations like:
int * (* (*fp1) (int) ) [10]; ---> declaration 1
int *( *( *[5])())(); --------> declaration 2
Start with the leftmost identifier and work your way out, remembering that absent any explicit grouping [] and () bind before *, e.g:
*a[] -- is an array of pointer
(*a)[] -- is a pointer to an array
*f() -- is a function returning pointer
(*f)() -- is a pointer to a function
Thus, we read int *(*(*fp1)(int))[10] as:
fp1 -- fp1
*fp1 -- is a pointer
(*fp1)(int) -- to a function
taking an int parameter
*(*fp1)(int) -- returning a pointer
(*(*fp1)(int))[10] -- to a 10-element array
*(*(*fp1)(int))[10] -- of pointer
int *(*(*fp1)(int))[10] -- to int
The declaration int *(*(*[5])())() presents a bit of a challenge since there's no identifier; you typically see this in function declarations where a parameter is of that type:
void foo(int *(*(*[5])())(), double);
It's the same principle as the unnamed int parameter in the declaration of fp1. The array gives us the clue, you can also look for the leftmost inner grouping of parentheses.
-- unnamed
[5] -- is a 5-element array ([] binds before *)
*[5] -- of pointers
(*[5])() -- to functions
*(*[5])() -- returning pointers
(*(*[5])())() -- to functions
*(*(*[5])())() -- returning pointers
int *(*(*[5])())() -- to int