More Pointers - V

The following topics are covered in this section:

Pointers to Structures

This is similar to creating pointers of other data types but you should know how to access structure elements through pointers.

struct phonebook
{
int pin;
int tel;
};
int main( )
{

phonebook record;
phonebook *p;
p=record; //Points to record
p->pin=60004;
p->tel=23451;
p=p+1; //Now points to record
p->pin=50023;
p->tel=89732;
p=record;
cout<<endl<<"The pincode is : "<<p->pin;
cout<<endl<<"The tel. no. is : "<<p->tel;
p=p+1; //Points to record
cout<<endl<<"\nThe pincode is : "<<p->pin;
cout<<endl<<"The tel. no. is : "<<p->tel;
return 0;
}

The output is:

The pincode is : 60004
The tel. no. is : 23451
The pincode is : 50023
The tel. no. is : 89732

You’ll notice that to access the individual elements we have made use of different operators. When you use pointers, you should not use the dot operator. Instead we make use of the arrow operator (->).

p->pin=60004;

Actually, the dot operator (or the member operator) can be used but you have to be careful about operator precedence. To use the member operator we’ll have to dereference the pointer and then use it. The following expression:

*p.pin

would be wrong. The dot operator is a post-fix operator and it has higher precedence over the dereferencing operator (which is a pre-fix operator). So to set it right we will have to use:

(*p).pin

Thus we could also have used the following code in our program:

cout<<endl<<"The pincode is : "<<(*p).pin;
cout<<endl<<"The tel. no. is : "<<(*p).tel;

Usually programmers do not use this method because there is a chance of forgetting the parentheses (and the arrow operator is simpler to use).

Also take note of how pointers can be used with structure arrays. Note that

p = p+1;

causes ‘p’ to point to the next structure variable ( i.e. record ).

Pointer to Pointer (Multiple Indirection)

In C++ you can create a pointer that will point to another pointer. In fact you can even create a pointer that points to a pointer that points to a pointer. But here we shall only deal with the case of a pointer that points to another pointer (the same concept can be extended to other cases).

The figure below should make the concept clear. Let ‘marks’ be an integer variable (let us assume that an integer occupies 4 bytes of memory).

int *p;
int marks=80;
p=&marks;
int **p2;
p2=&p;

Thus p2 is a pointer which points to a pointer of type integer (i.e. p2 points to ‘p’). The pointer p2 can be used for two purposes:

• p2 can be used to refer to the address of ‘p’
• p2 can also be used to access the value of marks.

If you want to access the value of marks through p2 then you can type:

cout<<**p2; //result will be 80 (which is stored in ‘marks’)

Pointer to constants:

When a pointer points to a constant term, the pointer cannot modify the value of the constant term. The declaration of a pointer to a constant is as follows:

const data-type *pointer-name;

Example:

const int num=20;
const int *ptr;
ptr = &num;

• The address of a constant cannot be assigned to a pointer unless the pointer is declared as pointing to a constant. The following is incorrect:

const int num=20;
int *ptr;
ptr=&num; //Error (pointer not declared as pointing to a constant)

• A pointer to a constant cannot be assigned to a non-constant pointer.

const int num=20;
const int *ptr;
ptr=&num;
int *ptr2;
ptr2=ptr; //Error because ptr2 is a pointer to a non constant

• The code fragment below is correct:

const int num=20;
const int *ptr;
ptr=&num;
const int *ptr3;
ptr3=ptr; //Correct because ptr3 is a pointer to a constant

Thus you can use pointers to constants as function parameters if you do not want the function to modify the argument.

Ø      The following is fine:

const int num=20;
const int *ptr;
ptr = &num;
ptr++;                                      //no problem

The pointer ‘ptr’ itself is not a constant (which means that we can change the value held in ptr at any time).

Constant Pointers:

A pointer, which is declared to be a constant, cannot be changed after initialization. Thus it will always retain the same value. Syntax for declaration:

The constant pointer has to be initialized and this value will be retained throughout the program. For example:

int num = 20;
int *const ptr = &num; //constant pointer initialized to address of num.

You cannot try to increment the pointer:

ptr++;

because ptr is a constant pointer and it’s value cannot be changed. You’ll get a compiler error saying “L-value is a constant”. But:

cout<<*(ptr+1);

is correct. Why? In this case we are only displaying the value stored at the next memory location; we are not trying to change the value held in ‘ptr’ (of course, this will produce some garbage value).

The following code fragment is incorrect:

int num=20;
int *const ptr; //has to be initialized here itself
ptr=&num;

Void Pointers

If a pointer is declared as pointing to void then it can point to any data type. The syntax for declaring a void pointer is:

void *pointer-name;

For example:

int num=20;
double db=1;
void *ptr;
ptr = &num;
ptr = &db;

In the above code fragment the void pointer ‘ptr’ is first assigned the address of an integer and then assigned the address of a double quantity. Though you can assign any data type you cannot attempt to access the value using the dereferencing operator. The following code will produce errors:

int num=20;
double db=1;
void *ptr;
ptr = &num;
ptr = &db;
cout<<*ptr; //Error – cannot use * to access value stored.

Also you cannot try to assign a void pointer to a pointer of some other data type. Pointer arithmetic is also not allowed in void pointers. If a function can operate on any kind of data type then the void pointer can be used (for example: the operator ‘new’ when overloaded will have a void pointer as its argument because this operator can work with any data type).

Go back to the Contents Page