The Dereference Operator (*)
You've seen the asterisk (*) in the declaration of a pointer. In C, the asterisk is called the dereference operator when it is used as a unary operator. (Sometimes, it's also called the indirection operator.) The value of a variable can be referenced by the combination of the * operator and its operand, which contains the address of the variable.
For instance, in the program shown in Listing 11.2, after the address of the character variable c is assigned to the pointer variable ptr_c, the expression *ptr_c refers to the value contained by c. Therefore, you can use the *ptr_c expression, instead of calling the variable c directly, to obtain the value of c.
Likewise, given an integer variable x and x = 1234, you can declare an integer pointer variable, ptr_x, for instance, and assign the left value (address) of x to ptr_x—that is, ptr_x = &x. Then, the expression *ptr_x returns 1234, which is the right value (content) of x.
WARNING
Don't confuse the dereference operator with the multiplication operator, although they share the same symbol, *.
The dereference operator is a unary operator, which takes only one operand. The operand contains the address (that is, left value) of a variable.
On the other hand, the multiplication operator is a binary operator that requires two operands to perform the operation of multiplication.
Null Pointers
A pointer is said to be a null pointer when its right value is 0. Remember, a null pointer can never point to valid data.
To set a null pointer, simply assign 0 to the pointer variable. For example:
char *ptr_c;
int *ptr_int;
ptr_c = ptr_int = 0;
Here ptr_c and ptr_int become null pointers after the integer value of 0 is assigned to them.
You'll see applications of null pointers used in control-flow statements and arrays later in this book.
Updating Variables via Pointers
As you learned in the previous section, as long as you link up a variable to a pointer variable, you can obtain the value of the variable by using the pointer variable. In other words, you can read the value by pointing to the memory location of the variable and using the dereferencing operator.
TYPE
This section shows you that you can write a new value to the memory location of a variable using a pointer that contains the left value of the variable. Listing 11.3 gives an example.
Listing 11.3. Changing variable values via pointers.1: /* 11L03.c: Changing values via pointers */
2: #include <stdio.h>
3:
4: main()
5: {
6: char c, *ptr_c;
7:
8: c = `A';
9: printf("c: address=0x%p, content=%c\n", &c, c);
10: ptr_c = &c;
11: printf("ptr_c: address=0x%p, content=0x%p\n", &ptr_c, ptr_c);
12: printf("*ptr_c => %c\n", *ptr_c);
13: *ptr_c = `B';
14: printf("ptr_c: address=0x%p, content=0x%p\n", &ptr_c, ptr_c);
15: printf("*ptr_c => %c\n", *ptr_c);
16: printf("c: address=0x%p, content=%c\n", &c, c);
17: return 0;
18: }
OUTPUT
After running the executable 11L03.exe from a DOS prompt on my machine, I get the following output displayed on the screen:
ANALYSIS
C:\app> 11L03
c: address=0x1828, content=A
ptr_c: address=0x1826, content=0x1828
*ptr_c => A
ptr_c: address=0x1826, content=0x1828
*ptr_c => B
c: address=0x1828, content=B
C:\app>
A char variable, c, and a char pointer variable, ptr_c, are declared in line 6 of List-ing 11.3.
The variable c is initialized with `A' in line 8, which is printed out, along with the address of the variable, by the printf() function in line 9.
Then, in line 10, the pointer variable ptr_c is assigned the left value (address) of c. It's not surprising to see the output printed out by the statements in lines 11 and 12, where the right value of ptr_c is the left value of c, and the pointer *ptr_c points to the right value of c.
In line 13 the expression *ptr_c = `B' asks the computer to write `B' to the location pointed to by the pointer *ptr_c. The output printed by the statement in line 15 proves that the content of the memory location pointed to by *ptr_c is updated. The statement in line 14 prints out the left and right values of the pointer variable ptr_c and shows that these values remain the same.
As you know, *ptr_c points to where the character variable c resides. Therefore, the expression *ptr_c = `B' actually updates the content (that is, the right value) of the variable c to `B'. To prove this, the statement in line 16 displays the left and right values of c on the screen. Sure enough, the output shows that the right value of c has been changed.
Pointing to the Same Thing
TYPE
A memory location can be pointed to by more than one pointer. For example, given that
c = `A' and that ptr_c1 and ptr_c2 are two character pointer variables, ptr_c1 = &c and ptr_c2 = &c set the two pointer variables to point to the same location in the memory.
The program in Listing 11.4 shows another example of pointing to the same thing with several pointers.
Listing 11.4. Pointing to the same thing with more than one pointer.1: /* 11L04.c: Pointing to the same thing */
2: #include <stdio.h>
3:
4: main()
5: {
6: int x;
7: int *ptr_1, *ptr_2, *ptr_3;
8:
9: x = 1234;
10: printf("x: address=0x%p, content=%d\n", &x, x);
11: ptr_1 = &x;
12: printf("ptr_1: address=0x%p, content=0x%p\n", &ptr_1, ptr_1);
13: printf("*ptr_1 => %d\n", *ptr_1);
14: ptr_2 = &x;
15: printf("ptr_2: address=0x%p, content=0x%p\n", &ptr_2, ptr_2);
16: printf("*ptr_2 => %d\n", *ptr_2);
17: ptr_3 = ptr_1;
18: printf("ptr_3: address=0x%p, content=0x%p\n", &ptr_3, ptr_3);
19: printf("*ptr_3 => %d\n", *ptr_3);
20: return 0;
21: }
OUTPUT
The following output is displayed on the screen by running the executable 11L04.exe from a DOS prompt on my machine (note that you might get different address values if you run the program on your machine):
C:\app> 11L04
x: address=0x1838, content=1234
ptr_1: address=0x1834, content=0x1838
*ptr_1 => 1234
ptr_2: address=0x1836, content=0x1838
*ptr_2 => 1234
ptr_3: address=0x1832, content=0x1838
*ptr_3 => 1234
C:\app>
ANALYSIS
As shown in Listing 11.4, line 6 declares an integer variable, x, and line 7 declares three integer pointer variables, ptr_1, ptr_2, and ptr_3.
The statement in line 10 prints out the left and right values of x. On my machine, the left value (address) of x is 0x1838. The right value (content) of x is 1234, which is the initial value assigned to x in line 9.
Line 11 assigns the left value of x to the pointer variable ptr_1 so that ptr_1 can be used to refer to the right value of x. To make sure that the pointer variable ptr_1 now contains the address of x, line 12 prints out the right value of ptr_1, along with its left value. The output shows that ptr_1 does hold the address of x, 0x1838. Then, line 13 prints out the value 1234, which is referred to by the *ptr_1 expression. Note that the asterisk * in the expression is the dereference operator.
In line 14, the *ptr_2 = &x expression assigns the left value of x to another pointer variable, ptr_2; that is, the pointer variable ptr_2 is now linked with the address of x. The statement in line 16 displays the integer 1234 on the screen by using the dereference operator * and its operand, ptr_2. In other words, the memory location of x is referred to by the second pointer *ptr_2.
In line 17, the pointer variable ptr_3 is assigned with the right value of ptr_1. Because ptr_1 now holds the address of x, the expression ptr_3 = ptr_1 is equivalent to ptr_3 = &x. Then, from the output made by the statements in lines 18 and 19, you see the integer 1234 again on the screen. This time the integer is referred to by the third pointer, *ptr_3.
- 3 views