Point to Point
Pointers are a very powerful, but primitive facility contained in the C language. Pointers are a throwback to the days of low-level assembly language programming and as a result they are sometimes difficult to understand and subject to subtle and difficult-to-find errors. Still it has to be admitted that pointers are one of the great attractions of the C language and there will be many an experienced C programmer spluttering and fuming at the idea that we would dare to refer to pointers as 'primitive'!
In an ideal world we would avoid telling you about pointers until the very last minute, but without them many of the simpler aspects of C just don't make any sense at all. So, with apologies, let's get on with pointers.
A variable is an area of memory that has been given a name. For example:
is an area of memory that has been given the name x. The advantage of this scheme is that you can use the name to specify where to store data. For example:
is an instruction to store the data value 10 in the area of memory named x. The variable is such a fundamental idea that using it quickly becomes second nature, but there is another way of working with memory.
The computer access its own memory not by using variable names but by using a memory map with each location of memory uniquely defined by a number, called the address of that memory location.
A pointer is a variable that stores this location of memory. In more fundamental terms, a pointer stores the address of a variable . In more picturesque terms, a pointer points to a variable.
A pointer has to be declared just like any other variable - remember a pointer is just a variable that stores an address. For example,
is a pointer to an integer. Adding an asterisk in front of a variable's name declares it to be a pointer to the declared type. Notice that the asterisk applies only to the single variable name that it is in front of, so:
int *p , q;
declares a pointer to an int and an int variable, not two pointers.
Once you have declared a pointer variable you can begin using it like any other variable, but in practice you also need to know the meaning of two new operators: & and *. The & operator returns the address of a variable. You can remember this easily because & is the 'A'mpersand character and it gets you the 'A'ddress. For example:
int *p , q;
declares p, a pointer to int, and q an int and the instruction:
stores the address of q in p. After this instruction you can think of p as pointing at q. Compare this to:
which attempts to store the value in q in the pointer p - something which has to be considered an error.
The second operator * is a little more difficult to understand. If you place * in front of a pointer variable then the result is the value stored in the variable pointed at. That is, p stores the address, or pointer, to another variable and *p is the value stored in the variable that ppoints at.
The * operator is called the de-referencing operator and it helps not to confuse it with multiplication or with its use in declaring a pointer.
This multiple use of an operator is called operator overload.
Confused? Well most C programmers are confused when they first meet pointers. There seems to be just too much to take in on first acquaintance. However there are only three basic ideas:
- To declare a pointer add an * in front of its name.
- To obtain the address of a variable us & in front of its name.
- To obtain the value of a variable use * in front of a pointer's name.
Now see if you can work out what the following means:
int *a , b , c;
b = 10;
a = &b;
c = *a;
Firstly three variables are declared - a (a pointer to int), and b and c (both standard integers). The instruction stores the value l0 in the variable b in the usual way. The first 'difficult' instruction is a=&b which stores the address of b in a. After this a points to b.
Finally c = *a stores the value in the varable pointed to by a in c. As a points to b, its value i.e. 1O is stored in c. In other words, this is a long winded way of writing
c = b;
Notice that if a is an int and p is a pointer to an int then
a = p;
is nonsense because it tries to store the address of an int, i.e. a pointer value, in an int. Similarly:
a = &p;
tries to store the address of a pointer variable in a and is equally wrong! The only assignment between an int and a pointer to int that makes sense is:
a = *p;