In most contexts, C++ interprets the name of an array as the address of its first element. Thus, the following statement makes pw
a pointer to type double
and then initializes pw
to wages
, which is the address of the first element of the wages
array:
double * pw = wages;
For wages
, as with any array, we have the following equality:
wages = &wages[0] = address of first element of array
Just to show that this is no jive, the program explicitly uses the address operator in the expression &stacks[0]
to initialize the ps
pointer to the first element of the stacks array.
Next, the program inspects the values of pw
and *pw
. The first is an address, and the second is the value at that address. Because pw
points to the first element, the value displayed for *pw
is that of the first element, 10000
. Then the program adds one to pw
. As promised, this adds eight to the numeric address value because double
on this system is 8 bytes. This makes pw
equal to the address of the second element. Thus, *pw
is now 20000
, the value of the second element (see Figure 4.10). (The address values in the figure are adjusted to make the figure clearer.)
After this, the program goes through similar steps for ps
. This time, because ps
points to type short
and because short
is 2 bytes, adding 1 to the pointer increases its value by 2 (0x28ccea + 2 = 0x28ccec in hexadecimal). Again, the result is to make the pointer point to the next element of the array.
Adding one to a pointer variable increases its value by the number of bytes of the type to which it points.
Now consider the array expression stacks[1]
. The C++ compiler treats this expression exactly as if you wrote it as *(stacks + 1)
. The second expression means calculate the address of the second element of the array and then find the value stored there. The end result is precisely what stacks[1]
means. (Operator precedence requires that you use the parentheses. Without them, 1
would be added to *stacks
instead of to stacks
.)
The program output demonstrates that *(stacks + 1)
and stacks[1
] are the same. Similarly, *(stacks + 2)
is the same as stacks[2]
. In general, wherever you use array notation, C++ makes the following conversion:
arrayname[i] becomes *(arrayname + i)
And if you use a pointer instead of an array name, C++ makes the same conversion:
pointername[i] becomes *(pointername + i)
Thus, in many respects you can use pointer names and array names in the same way. You can use the array brackets notation with either. You can apply the dereferencing operator (*
) to either. In most expressions, each represents an address. One difference is that you can change the value of a pointer, whereas an array name is a constant:
pointername = pointername + 1; // valid
arrayname = arrayname + 1; // not allowed
A second difference is that applying the sizeof
operator to an array name yields the size of the array, but applying sizeof
to a pointer yields the size of the pointer, even if the pointer points to the array. For example, in Listing 4.19, both pw
and wages
refer to the same array. But applying the sizeof
operator to them produces the following results:
24 = size of wages
array <<
displaying sizeof wages
4 = size of pw
pointer <<
displaying sizeof pw
This is one case in which C++ doesn’t interpret the array name as an address.
In short, using new
to create an array and using a pointer to access the different elements is a simple matter. You just treat the pointer as an array name. Understanding why this works, however, is an interesting challenge. If you actually want to understand arrays and pointers, you should review their mutual relationships carefully.
18.188.37.136