Previous | Table of Contents | Next |
Pointer values are generated with the unary & operator, which we will refer to as the pointer to operator, although many programmers call it the address of operator. Applied to any object or function, the & operator generates a pointer to that object, which we might then assign to a pointer variable. For example, given the int variable
int i = 5;
we can apply the & operator to it and assign the resulting pointer to the pointer variable ip using the simple assignment
ip = &i;
We say that ip now points to i; it is useful to visualize the situation with a picture like this:
Notice that there is a very important difference between the contents of a pointer variable and what the pointer points to. In the example just given, the contents of the pointer variable ip consist of a pointer (represented in the figure by an arrow), while what that pointer points to is an int object containing the value 5, which happens also to be the variable i. (Notice also that the & operator has two different meanings, depending on whether it is used as a unary or binary operator. It is in this respect similar to the - operator, and as well shortly see, to the * operator.)
After a pointer has been set to point somewhere, we access the value pointed to with the unary indirection or contents of operator, *. Continuing with the ip example, if we write
printf(%d\n, *ip);
the second argument to printf, the expression *ip, means fetch the value pointed to by ip. Because ip is of type pointer-to-int, the compiler assumes that the value pointed to is an int. (And an int is expected by the printf format specifier %d, so this is an appropriate second argument.) However, the * operator does not only fetch values via pointers; it can also be used to set values via pointers, when an expression involving * appears on the left-hand side of assignment operator:
*ip = 7;
This fragment stores the value 7 in the location pointed to by ip (which, if nothing has changed in the meantime, is still the variable i).
Pointers can be manipulated in a number of ways, some of which involve the pointers themselves and some of which involve the values pointed to. Weve seen one example of pointer assignment, in the line
ip = &i;
The & operator created a new pointer, but naturally enough, it is also possible to assign existing pointer values. Given a second pointer variable ip2, the assignment
ip2 = ip;
creates, in ip2, a copy of the pointer in ip: ip2 now points to the same object that ip does.
When youre writing pointer expressions and verifying their correctness, it is useful to think of the & operator as adding a level of pointerness (or, formally, a level of indirection), and to think of the * operator as taking away a level. For example, in the assignment
ip = &i;
the & on the right-hand side adds a level of indirection (a level of pointerness) to the int variable i, giving a pointer- to-int on the left, a pointer-to-int on the right, and a balanced, type-correct expression. Similarly, in
*ip = 7;
the * takes a pointer level away, leaving an int on the left, an int on the right, and another correct assignment. But none of
ip = i; i = ip; ip = 5; i = &i2; ip = *ip2; *ip = ip2;
are correct. Those in the first column all have pointer-to-int on the left and int on the right, while those in the second column all have int on the left and pointer-to-int on the right (assuming that i2 is another int variable).
Also, notice the difference between the two assignments
*ip2 = *ip;
and
ip2 = ip;
The first assignment copies the pointed-to values (without affecting the pointers, which have to point to different locations if the assignment is to have any effect), whereas the second assignment copies the pointers (without affecting the pointed-to values). Notice that both assignments are type correct.
There is one slight exception to the rigorous type-correlation rule outlined previously; it concerns the null pointer value. This is a distinct value that can be stored in a pointer variable to record that the pointer does not point anywhere at all. The question, of course, is how to specify this value. Rather than use a special keyword (such as Pascals nil), C uses a constant integer 0. So the pointer ip can be set to the null pointer value by writing
ip = 0;
The constant 0 is the only integer that can be assigned to a pointer variable; it is not correct to assign other constants or integer variables that happen to contain the value 0. As a convenience, several headers (see section 3.10.11) define the preprocessor macro NULL with the value 0 (or, depending on the implementation, with certain other equivalent forms of null pointer constant), allowing assignments like
ip = NULL;
(as long as one of those headers has been included).
Previous | Table of Contents | Next |