What’s the Address? Pointers
You yourself may have acted as a pointer in the past. Have you ever been asked where someone lives? If that house was nearby, you may have pointed it out.
The pointer performs a similar function. A pointer points to another variable or constant. Of course, the pointer does not point with an arm and fingers as you would. Rather, the pointer’s value is the address of the variable or constant to which it points. Indeed, you may have done something similar. If you were asked where someone lives and that house was not close enough to physically point out, you instead may have provided an address by which the house could be located.
Pointers have had a reputation among programming students for being difficult to learn. I think that reputation is overblown; pointers are not difficult if you take the time to understand what they do. In any event, difficult or not, it is important to learn about pointers. Some C++ tasks are performed more easily with pointers, and other C++ tasks, such as dynamic memory allocation, cannot be performed without them.
So, on that note, let’s now learn how to create and work with pointers.Declaring a Pointer
Like any variable or constant, you must declare a pointer before you can work with it. The syntax of declaring a pointer is almost the same as declaring a variable which stores a value rather than an address. However, the meaning of the pointer’s data type is quite different than the meaning of the data type of a variable which stores a value rather than an address.Syntax of a Pointer Declaration
The syntax of declaring a pointer is almost the same as the syntax of declaring the variables we have worked with in previous chapters. The following statement declares an integer pointer variable: int* iPtr;
The asterisk you use to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used in a declaration, so in this context it is being used to designate a variable as a pointer. Later in this chapter, we will use the asterisk for a third purpose, as an indirection operator.
NOTE: It is common in C++ for a symbol to have different meanings depending on the context. For example, an ampersand (&) in an argument list means you are passing an argument by reference, whereas an ampersand in front of a variable name is the address operator.
The integer pointer variable also can be declared with the asterisk preceding the variable name instead of following the data type:
Either alternative syntax is equally correct because the compiler generally ignores white spaces between an operator and a variable name, constant name, or number. Indeed, the following pointer declaration also works:
My preference is the first example, in which the asterisk follows the data type and is separated by a white space from the variable name, since (in my opinion) it best signifies that the variable is a pointer. However, all three syntax variations are correct. In any of these variations, the only difference between declaring a pointer variable and a variable which stores a value rather than an address is the asterisk between the data type and the pointer name.The Meaning of Pointer Data Types
While the syntax of declaring a pointer is almost the same as declaring the variables and constants which store a value rather than an address, the meaning of the data type in the declaration of a pointer is different than in the declaration of those other variables and constants.
With the variables we have worked with previously, the data type in the variable declaration describes the type of data that can be stored in that variable. Thus, the value of an integer variable or constant is an integer, the value of a character variable or constant is a character, and so forth.
However, with a pointer, the data type in the declaration means something different, namely the data type of another variable (or constant) whose memory address is the value of the pointer. In other words, the value of an integer pointer must be the address of an integer variable or constant, the value of a float pointer must be the address of a float variable or constant, and so forth.
The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to. This is demonstrated by the following program, which uses the sizeof operator to show that the sizes of pointers of different data types are the same (a long data type uses 4 bytes on my operating system and compiler) even though the different data types (int, float, char) are not all the same size:
#include <iostream> using namespace std;
int main ()
The output is therefore:
The size of iPtr is 4
Otherwise, a pointer is similar to the variables or constants we have studied previously. A pointer itself may be a variable or a constant, and like other variables or constants, it is also stored at a memory address. What distinguishes a pointer is that its value is the memory address of another variable or constant.Assigning a Value to a Pointer
This section will explain how you assign a value to a pointer. Though, before I explain how, perhaps I should explain why.Why You Should Not Try to Use an Unassigned Pointer
Back in elementary school we were taught a verse: “I shot an arrow into the air, where it lands, I don’t care.” Looking back, I wonder why young children were taught this verse. It may rhyme, but its message is really not appropriate for little ones. However, when you declare a pointer but then use it without first assigning it a value, you are, alas, doing the programming equivalent of that verse.
The following program declares a pointer and then attempts to output its value without first assigning it a value:
#include <iostream>> using namespace std;
int main ()
The result, depending on your compiler and operating system, may be a compiler error, a runtime error, or a computer that locks up. Regardless, attempting to use a declared pointer without first assigning it a value is not a good idea.
As you may recall from previous chapters, when you declare a variable and then attempt to output its value without first assigning it a value, the result is a so-called “garbage value” that makes little sense. The reason for this result is that the computer attempts to interpret whatever value is left over from previous programs at the address of the variable.
When the variable is a pointer, that leftover value is interpreted as another memory address, which the pointer then tries to access when you attempt to use it. There are a number of memory address ranges that you are not permitted to access programmatically, such as those reserved for use by the operating system. If the leftover value is interpreted as one of those prohibited addresses, the result is an error.Null Pointers
If it is too early in your code to know which address to assign to the pointer, then you first assign the pointer NULL, which is a constant with a value of zero defined in several standard libraries, including iostream. The following program does so:
int main ()
NOTE: You also could use initialization instead of declaration followed by assignment, thus combining the first two statements in main to int* iPtr = NULL.
The resulting output is
The address of x using iPtr is 00000000
A pointer that is assigned NULL is called a null pointer.
On most operating systems, programs are not permitted to access memory at address 0 because that memory is reserved by the operating system. You may now be thinking: “Wait a minute! He just told me how bad it was to risk having pointers point to memory addresses reserved by the operating system. Now he’s having us do that on purpose.”However, the memory address 0 has special significance; it signals that the pointer is not intended to point to an accessible memory location. Thus, if it is too early in your code to know which address to assign to a pointer, you should first assign the pointer to NULL, which then makes it safe to access the value of a pointer before it is assigned a “real” value such as the address of another variable or constant.
blog comments powered by Disqus