Type declaration involves three operators: array [SIZE]
, pointer *
and function (type1 param1, type2 param2, ...)
. Remember that all the three operators are right-associative.
char *(*c[10])(int **p);
Let's add more parenthesis to make the associativity more clear.
char *((*(c[10]))(int *(*p)))
Start from c
, the variable.
c[10]
means "c is an array of 10 elements, but each element is a ..."
Then see the *
beside it. *(c[10])
means "c is an array of 10 elements, each element is a pointer pointing to ..."
Then (*(c[10]))(int *(*p))
means "c is an array of 10 elements, each element is a pointer to a function, which returns ..." Using similar methods we see the function takes one parameter which is "a pointer to a pointer to an int".
Then *((*(c[10]))(int *(*p)))
means "c is an array of 10 elements, each element is a pointer to a function, which returns a pointer to a ..."
Finally char *((*(c[10]))(int *(*p)))
means "c is an array of 10 elements, each element is a pointer to a function, which returns a pointer to a char". That's it.
I find the Clockwise/Spiral Rule very useful. See http://c-faq.com/decl/spiral.anderson.html
But I'd rather add more brackets than using spirals.