Is there a reason the language designers of c used the star for both defining a pointer type
int* x;
and dereferencing a pointer?
int y = *x;
Using the same character for two different things seems confusing, especially since they're always used in the same context.
There is an excellent answer on this topic on Quora by Brian Bi. I reproduce it here verbatim. http://www.quora.com/C-programming-language/Why-doesnt-C-use-better-notation-for-pointers
The fact that an asterisk is used when declaring a pointer and an asterisk is used when dereferencing a pointer is not some sort of usability glitch in C. It is intentional.
There are two other notations that work like this. You use square brackets when declaring an array, and you use square brackets when accessing an array. You use parentheses when declaring a function pointer, and you use parentheses when calling a function pointer.
Declaration follows use.
Consider the following declaration:
int *a;
This declaration tells you that
*a
is of typeint
. In other words,a
is a pointer to int.How about this:
int *a[10];
This declaration tells you that
*a[i]
(wherei
is between 0 and 9, inclusive) is of typeint
. Since array indexing has higher precedence than pointer dereferencing, this tells you thata
is something that you can use[]
on (*i.e., *an array), then use*
on (i.e., a pointer)... and you will get anint
as a result. In other words,a
is an array[10] of pointers to int.int (*a)[10];
This declaration tells you that
(*a)[i]
is of typeint
. Sincea
is something you can use*
on, it must be a pointer. And then you can use[]
on the result to get anint
. So we see that the type ofa
must be pointer to array[10] of int.Notice that the above two declarations differ only in parentheses! But you don't have to memorize where parentheses should go for every type you might want to declare. Write down how you would use the variable, and slap the final type on at the beginning, just as in the above two examples. Any parentheses you have to insert for precedence reasons, include as well in the declaration.
Many C programmers have trouble remembering how to declare function pointers. This, too, becomes easy when you remember that declaration follows use. For example, let's declare a function pointer that we could use to hold the address of the function
strcpy
. This variable is something that, in order to use, you first dereference (with*
), then call, using()
, where the parentheses contain two arguments; the first beingchar*
, and the secondconst char*
. And the result is achar*
.Let's call our function pointer
p
. The first thing we do is dereference, so we write down*p
. Then we call*p
with the argumentschar*
andconst char*
, so write those down in parentheses next to*p
:(*p)(char*, const char*)
. (The parentheses are required around*p
because function calling has higher precedence than dereferencing.) Finally, prepend the result of the usage, that is, thechar*
the function returns. So our declaration is:char* (*p)(char*, const char*);
const
is a special case. The keywordconst
in a declaration applies to whatever thing you would have if you only partially use the variable, but stop once you "get" to it. It means that that particular thing can't be changed.Now, I'm sure you know that
const char *s;
declares a pointer to constantchar
s. That makes sense, since the thing at the beginning isconst char
, i.e., the result of*s
is aconst char
. However, you can also write it in the formchar const *s;
. The interpretation is that we can "get" as far as*s
, and then we see the wordconst
, so it means what we have up to this point isconst
. Ignoring theconst
for a moment, we seechar
. So*s
is achar
, and it's alsoconst
because the wordconst
precedes*s
.Now what about
char *const s;
? This means const pointer to char. The pointer can't be changed, but the thing it points to can. This is because the keywordconst
comes directly befores
, so it "lies in the way" of the dereferencing operator, so to speak.s
isconst
before it is dereferenced, but*s
is notconst
. The declarationschar const *const s;
orconst char *const s;
mean const pointer to const char.For double (and higher) pointers, it's the same deal.
const char **p;
declares a pointer to pointer to const char, as doeschar const **p;
. However,char *const *p;
declares a pointer to const pointer to char, andchar **const p;
delcares a const pointer to pointer to char.Just remember that declaration follows use, and you'll never be confused by declaration syntax again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With