Вы находитесь на странице: 1из 6

C++ Programming – Pointers NIBM

Introduction to Pointers
Pointers are one of the most powerful and confusing aspects of the C or C++ language. A pointer is a variable that
holds the address of another variable. To declare a pointer, we use an asterisk (* in-direction operator) between
the data type and the variable name:
int *pnPtr; // a pointer to an integer value
double *pdPtr; // a pointer to a double value

Note that an * (in-direction operator) 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 (&):

int nValue = 5;double *pdPtr; // a pointer to a double value


int *pnPtr = &nValue; // assign address of nValue to pnPtr

Conceptually, you can think of the above snippet like this:

The type of the pointer has to match the type of the variable being pointed to:

int nValue = 5;
double dValue = 7.0;

int *pnPtr = &nValue; // ok


double *pdPtr = &dValue; // ok
pnPtr = &dValue; // wrong -- int pointer can not point to double value
pdPtr = &nValue; // wrong -- double pointer can not point to int value

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.

int nValue = 5;
cout << &nValue; // prints address of nValue
cout << nValue; // prints contents of nValue

int *pnPtr = &nValue; // pnPtr points to nValue


cout << pnPtr; // prints address held in pnPtr, which is &nValue
cout << *pnPtr; // prints contents pointed to by pnPtr, which is contents
f l
Pointers can also be assigned and reassigned:

int nValue1 = 5;
int nValue2 = 7;
int *pnPtr;
pnPtr = &nValue1; // pnPtr points to nValue1
cout << *pnPtr; // prints 5
pnPtr = &nValue2; // pnPtr now points to nValue2
cout << *pnPtr; // prints 7

Diploma In Computer System Design- Part Time 1


C++ Programming – Pointers NIBM

Void pointers
The void pointer, also known as the generic pointer, is a special type of pointer that can be pointed at objects of
any data type! A void pointer is declared like a normal pointer, using the void keyword as the pointer’s type:
void *pVoid; // pVoid is a void pointer

A void pointer can point to objects of any data type:


int nValue;
float fValue;

void *pVoid;
pVoid = &nValue; // valid
pVoid = &fValue; // valid

However, because the void pointer does not know what type of object it is pointing to, it can not be dereferenced!
Rather, the void pointer must first be explicitly cast to another pointer type before it is dereferenced.

Null pointers
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:

int *pnPtr; Note that in this example, the * is not a


pnPtr = 0; // assign address 0 to pnPtr dereference operator. It is a pointer
declaration. Thus we are assigning
//or shorthand address 0 to pnPtr, not the value 0 to
int *pnPtr = 0; // assign address 0 to pnPtr 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:
int *pnPtr = NULL; // assign address 0 to pnPtr

Because null pointers point to 0, they can be used inside conditionals:


if (pnPtr)
cout << "pnPtr is pointing to an integer.";
else
cout << "pnPtr is a null pointer.";

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:

char *pchValue; // chars are 1 byte


int *pnValue; // ints are usually 4 bytes

cout << sizeof(pchValue) << endl; // prints 4


cout << sizeof(pnValue) << endl; // prints 4

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.

Diploma In Computer System Design- Part Time 2


C++ Programming – Pointers NIBM
What values does this program print? Assume a short is 2 bytes, and a 32-bit machine

short nValue = 7; // &nValue = 0012FF60


short nOtherValue = 3; // &nOtherValue = 0012FF54
short *pnPtr = &nValue;

cout << &nValue << endl;


cout << nValue << endl;
cout << pnPtr << endl;
cout << *pnPtr << endl;
cout << endl;

*pnPtr = 9;

cout << &nValue << endl;


cout << nValue << endl;
cout << pnPtr << endl;
cout << *pnPtr << endl;
cout << endl;

pnPtr = &nOtherValue;

cout << &nOtherValue << endl;


cout << nOtherValue << endl;
cout << pnPtr << endl;
cout << *pnPtr << endl;
cout << endl;

cout << sizeof(pnPtr) << endl;


cout << sizeof(*pnPtr) << endl;

A short explanation about the 4 and the 2. A 32-bit machine means that pointers will be 32 bits in length, but
sizeof() always prints the size in bytes. 32 bits is 4 bytes. Thus the sizeof(pnPtr) is 4. Because pnPtr is a pointer to a
short, *pnPtr is a short. The size of a short in this example is 2 bytes. Thus the sizeof(*pnPtr) is 2.

Pointers and Arrays


Pointers and arrays are intricately linked in both the C and C++ languages. In C, you learned how to declare an
array of variables:
int anArray[5]; // declare array of 5 integers

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:

int anArray[5] = { 9, 7, 5, 3, 1 };

// dereferencing an array returns the first element (element 0)


cout << *anArray; // prints 9!

char szName[] = "Jason"; // C-style string (also an array)


cout << *szName; // prints 'J'

Pointer arithmetic
Both C and C++ languages allow 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.

Diploma In Computer System Design- Part Time 3


C++ Programming – Pointers NIBM

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 2 bytes), pnPtr+3 means 3 integers after pnPtr, which is 6 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.

short nValue = 7;
short *pnPtr = &nValue;

cout << pnPtr << endl; Because a short is 2 bytes, each address differs by 2.
cout << pnPtr+1 << endl;
cout << pnPtr+2 << endl;
cout << pnPtr+3 << endl;

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.

Pointer arithmetic and arrays


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:
int anArray[5] = { 9, 7, 5, 3, 1 };
cout << *(anArray+1) << endl; // prints 7

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.

Arrays of Pointers
We can declare an array of pointers very easily. It is done like this:
int* hello[10];

This declares an array of 10 pointers, each of which points to an integer. The first pointer is called hello[0], the
second is hello[1], and so on up to hello[9]. These start of un-initialized - they point to some unknown point in
memory. We could make them point to integer variables in memory like this:

{
int* hello[10];
int a = 51, b = 46,……… c = 109;
hello[0] = &b;
hello[1] = &c;
hello[2] = &a; // etc.
}

Diploma In Computer System Design- Part Time 4


C++ Programming – Pointers NIBM

#include <iostream.h>

int* hello[10];

// Display all the pointer values


void display ()
{ int i;
// Display what each pointer in the array points to.
for (i = 0; i < 10; i++)
cout << *hello[i] << " ";
cout << endl;
}

void main ()
{ int a = 46, b = 109, c = 51, d = 66, e = 82, f = 47,
g = 40, h = 36, k = 70, l = 79;
hello[0] = &a;
hello[1] = &b;
hello[2] = &c;
hello[3] = &d;
hello[4] = &e;
hello[5] = &f;
hello[6] = &g;
hello[7] = &h;
hello[8] = &k;
hello[9] = &l;

int* temp;
int i,j;

display(); // Display the values before sorting

Pointers to Arrays
Suppose you have an array of integer values called v. You can declare a pointer to a integer value and make it point
to the array as per normal:
This piece of code displays the number which the
int v[5] = {1004, 2201, 3000, 432, 500}; pointer p points to, which is the first number in
int * p = v; the array, namely 1004. Note we deliberately
didn't use the & sign when we set up the pointer.
cout << *p << endl; As we said earlier it is not needed as array
variable is a pointer itself to the first element of
the array.

The most important thing you have to remember is that, C++ tends to treat arrays almost as though they were
pointers, which is why you can set a pointer to an array straight rather than using the "address of" operator. The
instruction p = v makes the pointer point to the address of the array. The number at this address is the first element
of the array, so that is the value produced when you access *p:

C++ gives some extra arithmetic instructions that let you use the pointer to the array more flexibly:

p++ : This instruction increases the pointer so that it points to the next element of the array. If you followed it with
the instruction cout << *p; then it would display the number 2201, which is the contents of element v[1] (i.e. the
second element).

Similarly, you can use instructions such as += and -= to refer to different elements in the array:

Diploma In Computer System Design- Part Time 5


C++ Programming – Pointers NIBM

p+=2;

p--;

You can even refer to the different array elements without having to alter the value of p. We have already used *p to
refer to the first element of the array (or subsequent elements if you have been updating p with += or -=), but you
can use *(p+1) to refer to the next element after *p, *(p+2) to refer to the one after that etc.

Diploma In Computer System Design- Part Time 6

Вам также может понравиться