Monday 18 October 2010

33. Pointer Expressions

Let us now see what are pointers and how they can be used in various expressions. If i=5 then expression &i returns the adderss of i. If we so desire, this address can be collected in avariable by saying,

j=&i;

But remember that j is not an ordinary variable like any other integer variable. It is a variable, which contains the address of another variable. Since j is a variable the compiler ust probide it space in memory. Once again, the following memory map would illustrate the contents of and j.

As you can see, i's value is 5 and j's value is i's address.

But wait, we can't use j in program without declaring it. And since j is a variable, which contains the address of i, it is declared as,

int *j;

This declaration tells the conpiler that j will be used to store the address of an integer value - in other words j points to an integer. How do we justify the usage of  * (pointer).

int *j;

Let us go by the meaning of *. It stand for 'value at address'. Thus, int *j would mean, the value at the address contained in j is an int.

Look at the following declarations,

int *alpha;
char *ch;
float *s;

Here, alpha, ch and s are declared as pointer variables, i.e. variables capable of holding addresses. Remember that, addresses are always going to be whole numbers, therefore pointers always contain whole numbers. The declaration float *s does not mean that s is going to contain a floating-point value. What it means is, s is going to contain the address of a floating-point value. Similarly, char *ch means that ch is going to contain the address of a char value.

Pointer we know is a variable, which contains address of another variable. Now this variable itself could be another pointer. Thus, we now have a pointer, which contains another pointer's address. The following example should make this point clear.

#include<stdio.h>
main( )
{
int i=5;
int *j;
int **k;

j=&i;
k=&j;
printf(" \n Address of i = %u",&i);
printf(" \n Address of i = %u",j);
printf(" \n Address of i = %u",*k);
printf(" \n Address of j = %u",&j);
printf(" \n Address of j = %u",k);
printf(" \n Address of k = %u",&k);

printf("\n\n Value of j = %u",j);
printf("\n Value of k = %u",k);
printf("\n Value of i = %d",i);
printf("\n Value of i = %d",*(&i));
printf("\n Value of i = %d",*j);
printf("\n Value of i = %d",**k);
getch();
}

The output of the above program would be:

Address of i = 6589
Address of i = 6589
Address of i = 6589
Address of j = 3275
Address of j = 3275
Address of k = 7234

Value of j = 6589
Value of k = 3275
Value of i = 5
Value of i = 5
Value of i = 5
Value of i = 5

The following memory map would help you in tracing out how the program prints the above output.
Observe how the variables i, j and k have been declared,

int i;
int *j;
int **k;

Here, i is an ordinary int, j is a pointer to an int, whereas k is a pointer to a pointer. In principle, there could be a pointer to a pointer to a pointer, or a pointer to a pointer to a pointer/ There is no limit on how far can we go on extending this definition.

Taken from 'Understanding Pointers In C'
post by Arnob

2 comments: