The pointers always get me when I try my hands at C. Now, I’m not dumber than most people, and the basic idea is pretty clear to me. But what trips my brain each time is the notation of declaration.
It’s not always illogical. After all, as K&C points out,
. Okay, that seems innocent enough, but in fact it’s a two-edged sword. What about when you’re declaring a pointer as a parameter for a function, then calling the function? Compare these two short programs below:int *ip
is intended as a mnemonic; it says that the expression *ip
is an int
Listing 1. | Listing 2. |
---|---|
|
|
For the first program, it’s easy to see that the parameter of foo()
, i
, is assigned the contents of j
from main()
: you’re in effect saying:
- Let
foo()
have one parameter,i
, of typeint
. - From
main()
, assign the value ofj
, also of typeint
, toi
.
But for the second one, foo()
has to be called with an address (a pointer), and yet the declaration, with the mnemonic notation in place, seems to call for an int
:
- Let
foo()
have one parameter,*ip
, of typeint
. - From
main()
, assign the value of&j
, of type… uhh… pointer, to… uhh… ???
This difficulty for me to grasp what type of a parameter foo()
should be called with is due to the mnemonic notation in int *ip
: when you have an int <something>
as a parameter declaration, you expect to assign the parameter something that is of type int
— not something that is a pointer to an int
.
Now, if I give up the mnemonic and instead write the declaration as int* ip
, the code translates to natural language quite fluidly:
Listing 3. |
---|
|
- Let
foo()
have one parameter,ip
, which is a pointer to anint
. - From
main()
, assign the value of&j
, also a pointer to anint
, toip
.
Of course, this notation opens a whole new can of worms. Consider the following declaration:
int* i, j;
Is j
a pointer now, or just an int
? It’s way too open to misinterpretation to make this notation commendable despite the previous advantage in readability.
So I’m better off sticking to the mnemonic notation, and just trying to get my head around it. For that, I’m still in desperate need for an easy translation of such code into natural language.
Maybe the mnemonic is the root of the problem. It’s a really bad mnemonic because it almost always works, but then there’s (at least) this one case, where you’re better off not remembering it, because it screws up your logic if you do. So I should think of int *ip
as ip is a pointer to an
and just forget about the fact that it resembles a declaration of an int
int
called *ip
.