C++ Pointers
So what is the fundamental difference between C++ and C#/Java in the two code examples? One word—pointers—or more specifically, two words—pointer arithmetic. To demonstrate, let's replace the array-indexing syntax in the C++ example of Listing 2 with an implementation using pointers, as presented in Listing 4.
Listing 4C++ code using pointers.
// Pointers02.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; int myArray [] = {2, 15, 24, 36, 48}; int main () { int i=0; int *ptr = myArray; for (i=0 ; i < 5; i++, ptr++) { printf("myArray[%d]= %d\n", i, *ptr); } system ("pause"); return 0; }
Several interesting lines in this code relate to the pointers. The following line declares ptr as a pointer, as designated by the asterisk (*), and assigns it to the address of the array, myArray:
int *ptr = myArray;
The next line shows that we're incrementing the pointer inside the for loop. In this case, since the pointer is an integer pointer, it bumps up the location by the size of an integer:
for (i=0 ; i < 5; i++, ptr++)
Finally, we can access the actual value of the memory location with the following syntax:
printf("myArray[%d]= %d\n", i, *ptr);
As I just mentioned, the pointer can be accessed simply by using the asterisk prefix:
*ptr
Interestingly, if you leave out the asterisk you get the actual address of memory location. For example, take a look at the code in Listing 5 (notice that the asterisk is missing from the printf statement).
Listing 5Inspecting the actual memory addresses.
// Pointers02.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; int myArray [] = {2, 15, 24, 36, 48}; int main () { int i=0; int *ptr = myArray; for (i=0 ; i < 5; i++, ptr++) { printf("myArray[%d]= %d\n", i, ptr); // print actual memory address (not value) } system ("pause"); return 0; }
Perhaps even more interesting is the output that's produced, shown in Figure 6. Notice that instead of outputting the values of the array, this version outputs the actual addresses.
Figure 6 Specific memory addresses.
You can actually see that the first address is 17461248. It's important to understand that the address locations are incremented by the size of the pointer, which in this case is the size of an integer.
You can determine the size of a data type in C++ by using the sizeof() function:
int i = 0; printf( "The size of an integer is %d\n", sizeof( i ) );
With this code snippet, sizeof() verifies that the integer occupies four bytes in memory:
The size of an integer is 4.
Viewing the pointer arithmetic performed by the code in Figure 7, we can see that the addresses do indeed increment by four.
Figure 7 Memory locations of array items.
So why does C++ allow this type of pointer behavior, while Java and .NET don't?