Professional Documents
Culture Documents
The asterisk in the above specifies that we have a pointer variable. Let's say we want to define an
int variable and then we want to define a pointer variable, which will store the memory address of this int:
signed main()
{
int myval(7);
int* p_myval;
//Right now, p_myval contains no particular myval.
p_myval = &myval;
//Now, p_myval in this c++ program contains the memory address of the variable myval
}
With &myval, & is referred to as "the address-of operator". The expression &myval is of the c++ type
int*. We then store this int* myval in our int* variable, which is p_myval. Now, we will actually use this
pointer:
signed main()
{
int myval = 7;
int* p_myval = &myval;
*p_myval = 6;
}
With *p_myval = 6, the asterisk is referred to as "the dereference operator". It turns the expression from
an int* into an int. The statement has the effect of setting the myval of myval to 6. So now what are the
uses of pointers in c++? Let us see something about how and when they should be used:
Here's what the string (char c++ pointer) looks like in memory:
int main()
{
char my_name[] = "Code";
char* k( &my_name[1] );
}
signed main()
{
signed** p_p_cow;
}
An int* c++ pointer points to an int, so an int** points to an int*. In English: The variable p_cow above
stores a memory address. At that memory address exists a variable of type int*. This int* variable also
stores a memory address, at which exists an int. Take the following:
int main()
{
int cow(7);
int* p_cow = &cow;
int** p_p_cow(&p_cow);
int*** p_p_p_cow = &p_p_cow;
}
int main()
{
int cow(7);
int* p_cow = &cow;
int** p_p_cow(&p_cow);
int*** p_p_p_cow = &p_p_cow;
***p_p_p_cow = 8;
}
C++ Pointers are commonly used when working with strings. Let's define a function; this function will
be supplied with a string. We're going to change the 2nd, 5th and 7th characters of the string:
Or we can define a function, which will be supplied with a string. The function will return the first
instance of the character 't' in the string:
for ( ; *p ; ++p)
{
if ( *p == 't' ) return p;
}
return 0;
}
signed main()
{
Now I'm going to talk about c++ pointers and constness. If you want a const c++ pointer variable, a c+
+ pointer variable whose value you can't change after initialization, then stick the const directly beside
the variable's name:
signed main()
{
int myval = 5;
int myvalue2(8);
int* const p_k = &myval;
p_k = &myvalue2; //COMPILE ERROR
*p_k = 3; //No problem, the variable to which it points is non-const
If you want a non-const c++ pointer variable, but you want the variable to which it points to be const,
then:
signed main()
{
int myval(7);
int myvalue2 = 6;
const int* p_k = &myval;
p_k = &myvalue2; //No problem, the variable is non-const
*p_k = 7; //COMPILE ERROR
int myval(17);
int myvalue2 = 4;
const int* const p_k = &myval;
p_k = &myvalue2; //COMPILE ERROR
*p_k = 32; //COMPILE ERROR
anArray is actually a pointer that points to the first element of the array! Because the array variable is
a pointer, you can dereference it, which returns array element 0:
1 int anArray[5] = { 9, 7, 5, 3, 1 };
2
5
Pointer arithmetic
The C language allows you to perform integer addition or subtraction operations on pointers. If pnPtr
points to an integer, pnPtr + 1 is the address of the next integer in memory after pnPtr. pnPtr - 1 is
the address of the previous integer before pnPtr.
Note that pnPtr+1 does not return the address after pnPtr, but the next object of the type that pnPtr
points to. If pnPtr points to an integer (assuming 4 bytes), pnPtr+3 means 3 integers after pnPtr,
which is 12 addresses after pnPtr. If pnPtr points to a char, which is always 1 byte, pnPtr+3 means 3
chars after pnPtr, which is 3 addresses after pnPtr.
When calculating the result of a pointer arithmetic expression, the compiler always multiplies the
integer operand by the size of the object being pointed to. This is called scaling.
2 int *pnPtr = &nValue;
3
Outputs:
0012FF7C
0012FF80
0012FF84
0012FF88
As you can see, each of these addresses differs by 4 (7C + 4 = 80 in hexadecimal). This is because an
integer is 4 bytes on the author’s machine.
1 short nValue = 7;
2 short *pnPtr = &nValue;
3
Outputs:
0012FF7C
0012FF7E
0012FF80
0012FF82
It is rare to see the + and – operator used in such a manner with pointers. However, it is more
common to see the ++ or — operator being used to increment or decrement a pointer to point to the
next or previous element in an array.
If anArray is a pointer that points to the first element (element 0) of the array, and adding 1 to a
pointer already returns the next object, then anArray+1 must point to the second element (element 1)
of the array! We can verify experimentally that this is true:
1 int anArray[5] = { 9, 7, 5, 3, 1 };
The parentheses are necessary to ensure the operator precedence is correct — operator * has higher
precedence than operator +.
Note that *(anArray+1) has the same effect as anArray[1]. It turns out that the array indexing
operator ([]) actually does an implicit pointer addition and dereference! It just looks prettier.
We can use a pointer and pointer arithmetic to loop through an array. Although not commonly done
this way (using indices is generally easier to read and less error prone), the following example goes to
show it is possible:
01 const int nArraySize = 7;
02 char szName[nArraySize] = "Mollie";
03 int nVowels = 0;
05 {
06 switch (*pnPtr)
07 {
08 case 'A':
09 case 'a':
10 case 'E':
11 case 'e':
12 case 'I':
13 case 'i':
14 case 'O':
15 case 'o':
16 case 'U':
17 case 'u':
18 nVowels++;
19 break;
20 }
21 }
22
23 cout << szName << " has " << nVowels << " vowels" << endl;
This program uses a pointer to step through each of the elements in an array. Each element is
dereferenced by the switch expression, and if the element is a vowel, nVowels is incremented. The for
loop then uses the ++ operator to advance the pointer to the next character in the array. The for loop
terminates when all characters have been examined.