Reputation: 179
I've always been slightly confused as to how C type notation works. I don't have access to Google, and Bing is turning up garbage results.
For example: what does int *(*)[]
mean? I know already that it's a pointer to an array of integer pointers (I think), but why? In particular, I'm confused as to what the brackets are doing; yeah, int **[]
would be an array of pointers to pointers, but why does ()
change that?
Upvotes: 4
Views: 382
Reputation: 40625
To read such types, mentally add a variable name to the expression to turn it into a valid declaration. Then read it from the inside out, like you read all variable declarations in C:
int **[] -> int **a[];
a[] //[] has higher precedence than *, so `a` is an array
*a[] //this array contains pointers
**a[] //which dereference to pointers
int **a[]; //which dereference to int
So, int**[]
is the type of an array of pointers to pointers to int
.
With the other type, we get:
int *(*)[] -> int *(*a)[];
*a //a is a pointer
(*a) //(precedence control, only)
(*a)[] //which dereferences to an array
*(*a)[] //which contains pointers
int *(*a)[]; //which dereference to int
So, int*(*)[]
is the type of a pointer to an array of pointers to int
.
As you see, the parentheses have the effect of selecting the first *
operator before the []
. The later has higher precedence, so if you need a pointer to an array, you need to introduce the parentheses.
There are three operators which are relevant to type declarations, and it's important to know their precedence:
High precedence:
[] array subscript declares an array
() function call declares a function
Low precedence:
* dereference operator declares a pointer
Because the *
has lower precedence than either ()
or []
, you need to add the extra parentheses to declare pointers to arrays or functions:
int *a[]; //array of pointers, as a cast: `(int*[])`
int (*a)[]; //pointer to an array, as a cast: `(int(*)[])`
int *a(); //function returning a pointer, as a cast: `(int*())`
int (*a)(); //pointer to a function returning an `int`, as a cast: `(int(*)())`
Once you've understood this principle, no type expression in C will confound you anymore.
Upvotes: 6