Why is * used for both declaring pointers and dereferencing them? Basically, the notation of a variable declaration says what you must do to something to get something of the specified type. For example:
This is always the way that variables are declared in C.
Now, how about the declaration
int *r[10];
Is this
At this point, you must look at an operator precedence table to determine that if you were to call
*r[7];
then r[7] is evaluated first, so an array entry is accessed, and then it is dereferenced. Therefore, it must be an array of 10 pointers to integers.
How do you get the other? How do you declare a variable to be a pointer to an array of 10 integers? Like defining precedence for addition and multiplication, we too can use brackets for types:
int (*r)[10];
That is, if you dereference r and then use brackets, you get an integer.
For more fun with C declarations, see cdecl.
One of these declares that r cannot be changed, while the other declares that the value of r cannot be changed. From our reasoning above, we should be able to determine this:
Note that const int *r is identical to int const *r.
Also note that int const *const r and const int *const r also both mean the same thing: you cannot assign to r and you cannot assign to *r, either.