Pointers are one of the most powerful and confusing aspects of the C language. A
pointer is a variable that holds the address of another variable. To declare a pointer, we use an asterisk between the data type and the variable name:
Note that an asterisk placed between the data type and the variable name means the variable is being declared as a pointer. In this context, the asterisk is not a multiplication. It does not matter if the asterisk is placed next to the data type, the variable name, or in the middle — different programmers prefer different styles, and one is not inherently better than the other.
Since pointers only hold addresses, when we assign a value to a pointer, the value has to be an address. To get the address of a variable, we can use the
address-of operator (&):
Conceptually, you can think of the above snippet like this:

It is also easy to see using code:
4 | cout << &nValue << endl; |
On the author’s machine, this printed:
0012FF7C
0012FF7C
The type of the pointer has to match the type of the variable being pointed to:
5 | double *pdPtr = &dValue; |
Dereferencing pointers
The other operator that is commonly used with pointers is the
dereference operator (*). A dereferenced pointer evaluates to the
contents of the address it is pointing to.
The above program prints:
0012FF7C
5
0012FF7C
5
In other words, when pnPtr is assigned to &nValue:
pnPtr is the same as &nValue
*pnPtr is the same as nValue
Because *pnPtr is the same as nValue, you can assign values to it just as if it were nValue! The following program prints
7
:
Pointers can also be assigned and reassigned:
The null pointer
Sometimes it is useful to make our pointers point to nothing. This is called a
null pointer. We assign a pointer a null value by setting it to address 0:
or shorthand:
Note that in the last example, the * is not a dereference operator. It is a pointer declaration. Thus we are assigning address 0 to pnPtr, not the value 0 to the variable that pnPtr points to.
C (but not C++) also defines a special preprocessor define called NULL that evaluates to 0. Even though this is not technically part of C++, it’s usage is common enough that it will work in every C++ compiler:
Because null pointers point to 0, they can be used inside conditionals:
2 | cout << "pnPtr is pointing to an integer." ; |
4 | cout << "pnPtr is a null pointer." ; |
Null pointers are mostly used with dynamic memory allocation, which we will talk about in a few lessons.
The size of pointers
The size of a pointer is dependent upon the architecture of the computer — a 32-bit computer uses 32-bit memory addresses — consequently, a pointer on a 32-bit machine is 32 bits (4 bytes). On a 64-bit machine, a pointer would be 64 bits (8 bytes). Note that this is true regardless of what is being pointed to:
09 | cout << sizeof (pchValue) << endl; |
10 | cout << sizeof (pnValue) << endl; |
11 | cout << sizeof (psValue) << endl; |
As you can see, the size of the pointer is always the same. This is because a pointer is just a memory address, and the number of bits needed to access a memory address on a given machine is always constant.
Quiz
1) What values does this program print? Assume a short is 2 bytes, and a 32-bit machine
03 | short *pnPtr = &nValue; |
05 | cout << &nValue << endl; |
06 | cout << nValue << endl; |
08 | cout << *pnPtr << endl; |
13 | cout << &nValue << endl; |
14 | cout << nValue << endl; |
16 | cout << *pnPtr << endl; |
21 | cout << &nOtherValue << endl; |
22 | cout << nOtherValue << endl; |
24 | cout << *pnPtr << endl; |
27 | cout << sizeof (pnPtr) << endl; |
28 | cout << sizeof (*pnPtr) << endl; |
No comments:
Post a Comment