[ fromfile: pointers.xml id: refderefoperators ]
An object (in the most general sense) is a chunk of memory that can hold data. A variable is an object with a name recognized by the compiler. A variable's name can be used as if it is the object itself. For example, if you say:
int x = 5;
You can use x
to stand for the integer object whose value is 5, and you can manipulate the integer object directly through the name x
. For example:
++x ; // symbol x now refers to an integer with value 6
Each object has a memory address (where its data begins).
The unary &
operator, also known as the address-of operator, when applied to any object, returns the memory address of that object.
For example: &x
returns the memory address of x
.
An object that holds the memory address of another object is called a pointer. We say that the pointer points to the object at the stored memory address.
int* y = &x ;
In this example, y
points to the integer x
.
The asterisk *
following the type name int
indicates that y
is a pointer to int
.
Here the int
pointer y
is initialized to the address of the int
variable x
.
One of the powerful features of pointers is that, subject to rules that we will explore shortly, it is possible for a pointer of one type to hold the address of an object of a different (but related) type.
Zero (0
), often represented by the macro NULL
in C programs, is a special value that can be legally assigned to a pointer, usually when it is initialized or after it has been deleted.
0
is not the address of any object.
A pointer that stores the value 0
is called a null pointer.
Stroustrup recommends the use of 0
rather than the macro NULL
in C++ programs.
A pointer to a simple type uses exactly the same amount of memory as a pointer to a large complicated object.
That size is usually the same as sizeof(int)
on that machine.
The unary *
operator, also known as the dereference operator, when applied to a non-null pointer, returns the object at the address stored by the pointer.
Warning | |
---|---|
The symbol
|
Example 1.30. src/pointers/pointerdemo/pointerdemo.cpp
#include <QTextStream> int main() { QTextStream cout(stdout); int x = 4; int* px = 0 ; px = &x; cout << "x = " << x << " *px = " << *px << " px = " << px << " &px = " << &px << endl; x = x + 1; cout << "x = " << x << " *px = " << *px << " px = " << px << endl; *px = *px + 1; cout << "x = " << x << " *px = " << *px << " px = " << px << endl; return 0; } Output: OOP> ./pointerdemo x = 4 *px = 4 px = 0xbffff514 &px = 0xbffff510 x = 5 *px = 5 px = 0xbffff514 x = 6 *px = 6 px = 0xbffff514 OOP>
<include src="src/pointers/pointerdemo/pointerdemo.cpp" href="src/pointers/pointerdemo/pointerdemo.cpp" id="pointerdemo1" mode="cpp"/>
When Example 1.30 is run at different times, or on different machines, the memory addresses are likely to be different.
The variable x
accesses its data directly but the variable px
accesses the same data indirectly.
This is why the word indirection is often used to characterize the process of accessing data through a pointer.
The relationship between the two variables, x
and px
, is illustrated in Figure 1.4.
Because whitespace is ignored by the compiler, the location of whitespace can help or confuse the reader. To improve readability and maintainability of C++ code that contains pointer declarations, we recommend that
Each individual pointer should have its own declaration.
The asterisk should be placed immediately to the right of the type name.
T* ptr;
This declaration is unambiguous: ptr
is a pointer to type T
.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |