I usually think "int pointer a" when writing int *a
.
The right way to think of it — bear with me for a moment — is that when you write
int *ip;
you are saying that *ip
will be an int
. From this it can be deduced that ip
is a pointer to an int
.
This is the "declaration mimics use" strategy. In the declaration
int *ip;
we see that *ip
will be an int
, and in an expression later when we do something like
*ip = 42;
or
printf("%d\n", *ip);
we can see that *ip
is acting like an int
— the form *ip
in the declaration mimics the form *ip
when we later use it.
An important point is that when you declare variables in C, the syntax is not
type-name list-of-variables; /* WRONG */
The actual syntax is
type-name list-of-declarators;
On the left there's the name of a type, and on the right there's a list of things that will have that type — but the "things" are not necessarily simple variable names! In fact, there's a whole 'nother little programming language you can use while constructing the declarators. As a mildly extreme example, if you say
int i, j, a[10], *ip, f();
you are saying that i
, j
, a[]
, *ip
, and f()
will all have type int
— which is another way of saying that i
and j
will be plain int
variables, a
will be an array of int
, ip
will be a pointer to int
, and f
will be a function returning int
.
Now, going back to what you had said:
int b = *a;
stands for "int b
is value of a
", not "pointer of a
"
If you think of *
as meaning "contents of", the confusion should largely go away. If you think of *
as meaning "contents of", then the declaration
int *a;
is read as "the contents of a
will be an int
", and the initialization
int b = *a;
is read as "b
gets the contents of a
".
(But I'm not saying you have to think of it that way all the time. When I see int *a
, yes, I read it as "a
is a pointer to an int
". The explanation here is of how the notation came about. It can be confusing, but it's much less confusing if you understand where it came from and how it works.)
And with int *a = &b
the confusion then is perfect, as the new symbol &
now stands for "pointer of b
" again.
&
doesn't just mean "pointer", it means "make a pointer to" or "take the address of".
But the form
int *a = &b;
is definitely confusing, because you are not providing an initial value for *a
— you are in fact providing an initial value for the pointer a
itself. If you do it on two lines, you have
int *a;
a = &b;
You do not say
*a = &b; /* WRONG */
When you're working with pointers in C, you always have to be careful to distinguish between the pointer and what the pointer points to. When you say
a = &b;
you're making an assignment to the pointer a
. When you say
*a = 42;
you're making an assignment to what the pointer a
points to.
And when you say
int *a = &b;
you are simultaneously declaring the pointer, and providing an initial value for the pointer. (In that declaration you're not doing anything with what the pointer points to.)