Pointer Operators

The address operator (&) is a unary operator that returns the memory address of its operand. For example, assuming the declarations

int y = 5; // declare variable y int *yPtr; // declare pointer variable yPtr

the statement

yPtr = &y; // assign address of y to yPtr

assigns the address of the variable y to pointer variable yPtr. Then variable yPtr is said to "point to" y. Now, yPtr indirectly references variable y's value. Note that the use of the & in the preceding assignment statement is not the same as the use of the & in a reference variable declaration, which is always preceded by a data-type name.

Figure 8.2 shows a schematic representation of memory after the preceding assignment. The "pointing relationship" is indicated by drawing an arrow from the box that represents the pointer yPtr in memory to the box that represents the variable y in memory.

Figure 8.2. Graphical representation of a pointer pointing to a variable in memory.

Figure 8.3 shows another representation of the pointer in memory, assuming that integer variable y is stored at memory location 600000 and that pointer variable yPtr is stored at memory location 500000. The operand of the address operator must be an lvalue (i.e., something to which a value can be assigned, such as a variable name or a reference); the address operator cannot be applied to constants or to expressions that do not result in references.

Figure 8.3. Representation of y and yPtr in memory.

(This item is displayed on page 405 in the print version)

The * operator, commonly referred to as the indirection operator or dereferencing operator, returns a synonym (i.e., an alias or a nickname) for the object to which its pointer operand points. For example (referring again to Fig. 8.2), the statement

cout << *yPtr << endl;


prints the value of variable y, namely, 5, just as the statement

cout << y << endl;

would. Using * in this manner is called dereferencing a pointer. Note that a dereferenced pointer may also be used on the left side of an assignment statement, as in

*yPtr = 9;

which would assign 9 to y in Fig. 8.3. The dereferenced pointer may also be used to receive an input value as in

cin >> *yPtr;

which places the input value in y. The dereferenced pointer is an lvalue.

Common Programming Error 8.2

Dereferencing a pointer that has not been properly initialized or that has not been assigned to point to a specific location in memory could cause a fatal execution-time error, or it could accidentally modify important data and allow the program to run to completion, possibly with incorrect results.

Common Programming Error 8.3

An attempt to dereference a variable that is not a pointer is a compilation error.

Common Programming Error 8.4

Dereferencing a null pointer is normally a fatal execution-time error.

The program in Fig. 8.4 demonstrates the & and * pointer operators. Memory locations are output by << in this example as hexadecimal (i.e., base-16) integers. (See Appendix D, Number Systems, for more information on hexadecimal integers.) Note that the hexadecimal memory addresses output by this program are compiler and operating-system dependent, so you may get different results when you run the program.

Figure 8.4. Pointer operators & and *.

(This item is displayed on page 406 in the print version)

1 // Fig. 8.4: fig08_04.cpp 2 // Using the & and * operators. 3 #include 4 using std::cout; 5 using std::endl; 6 7 int main() 8 { 9 int a; // a is an integer 10 int *aPtr; // aPtr is an int * -- pointer to an integer 11 12 a = 7; // assigned 7 to a 13 aPtr = &a; // assign the address of a to aPtr 14 15 cout << "The address of a is " << &a 16 << " The value of aPtr is " << aPtr; 17 cout << " The value of a is " << a 18 << " The value of *aPtr is " << *aPtr; 19 cout << " Showing that * and & are inverses of " 20 << "each other. &*aPtr = " << &*aPtr 21 << " *&aPtr = " << *&aPtr << endl; 22 return 0; // indicates successful termination 23 } // end main  

The address of a is 0012F580 The value of aPtr is 0012F580 The value of a is 7 The value of *aPtr is 7 Showing that * and & are inverses of each other. &*aPtr = 0012F580 *&aPtr = 0012F580  

Portability Tip 8.1

The format in which a pointer is output is compiler dependent. Some systems output pointer values as hexadecimal integers, while others use decimal integers.

Notice that the address of a (line 15) and the value of aPtr (line 16) are identical in the output, confirming that the address of a is indeed assigned to the pointer variable aPtr. The & and * operators are inverses of one anotherwhen they are both applied consecutively to aPtr in either order, they "cancel one another out" and the same result (the value in aPtr) is printed.


Figure 8.5 lists the precedence and associativity of the operators introduced to this point. Note that the address operator (&) and the dereferencing operator (*) are unary operators on the third level of precedence in the chart.

Figure 8.5. Operator precedence and associativity.


Operators

Associativity

Type

()

[]

         

left to right

highest

++

--

static_cast<type>( operand )

left to right

unary (postfix)

++

--

+

-

!

&

*

right to left

unary (prefix)

*

/

%

       

left to right

multiplicative

+

-

         

left to right

additive

<<

>>

         

left to right

insertion/extraction

<

<=

>

>=

     

left to right

relational

==

!=

         

left to right

equality

&&

           

left to right

logical AND

||

           

left to right

logical OR

?:

           

right to left

conditional

=

+=

-=

*=

/=

%=

 

right to left

assignment

,

           

left to right

comma

Категории