Topic : A primer on Pointers
Page : 1 Next >>
Go to page :

A primer on Pointers

Introduction to & and * operators

Consider the following C declaration.

int n=4;

This declaration tells the compiler to

Reserve in memory to hold an integer value.
Associate variable name ‘n’ with this memory location.
Store value 4 at the location.

Location name       n

Value at location    4

Location number    4096

The computer has selected 4096 memory location to store the value of n. The location 4096 is a number not to be relied upon, because some other time the computer may choose a different location.

The important point is that n’s address in memory is a number.

We can print the address of n through the following program.

main()

{

int n=4;

printf(“Value of n is %d\n”,n);

}

The output is

Value n = 4

If you see the first printf() statement you observe that ‘&’ operator is used. The operator ‘&’ is called ‘address of operator’. The expression &n returns the address of variable n. In this case the address happens to be 4096.

The & operator when used with a variable name gives the address of the variable. On the other side of the coin we have another pointer operator ‘*’, also known as ‘value at address’ or ‘indirection operator’.

The ‘*’ operator when used with any ‘address’ gives the value at that address.

Consider the following example.

main()

{

int n=4;

printf(“Value of n = %d\n”,n);

printf(“Value at address of n = %d\n”,*(&n));

}

The output would be

Value of n = 4

Value at address of n = 4

Note that printing the value of   *(&n)   is same as printing the value of n.

Pointer expressions

We have now learnt that the address of any variable is also a number. And the expression &n returns the address of n. Hence the address (which is a number) can be stored in another variable saying

p=&n;

But p is not an ordinary variable like any other integer variable. It is a variable which contains an address of another variable ( n in this case).

Since p is a variable, the compiler must provide it space in memory.

Once again the following memory map would illustrate the contents of n and p.

Location name       n                         p

Value at location    4                    4096

Location number    4096              1600

As you can see, n’s value is 4  and p’s value is n’s address.

But we can’t use variable p, without declaring it. And since p is a variable which contains the address of n, it is declared as

int   *p;

The int  * conveys us that the value at the address contained in p is int.

The following program demonstrated the relationships we have been discussing.

main()

{

int n = 4;

int   *p;

p=&n;

printf(“Value of p = %u\n”,p);

printf(“Value of n = %d\n”,n);

printf(“Value of n = %d”, *(&n));

printf(“Value of n = %d\n”,*p);

}

The output would be

Value of p = 4096

Value of n = 4

Value of n = 4

Value of n = 4

If you don’t  understand the program’s output of the meaning of expression &n, &p,*p and *(&p) it is advised to re read from the first.

Pointer declarations

int  *i;

char   *ch;

float   *f;

Here i,  ch,  f are declared as pointer variables capable of holding address. Since addresses are always whole numbers, pointers are always whole numbers.

The essence is “Pointers are variables which contain addresses, and since addresses are always whole numbers, pointers would always contain numbers”

The declaration float   *f does not mean that s is going to contain a floating point value. It means that f is going to contain the address of a floating point variable.

Similarly, char   *ch  means that ch is going to contain the address of a char value. Or in other words, the value at address stored in ch is going to be a char.

Pointer to pointer

We have learnt that a pointer variable contains the 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.

main()

{

int =3;

int   *j;

int   **k;

j=&i;

k=&j;

printf(“Value of j = %u\n”,j);

printf(“Value of k = %u\n”,k);

printf(“Value of i = %d\n”,i);

printf(“Value of i = %d\n”,*(&i));

printf(“Value of i = %d\n”,*j);

printf(“Value of i = %u\n”,**k);

}

The output would be

Value of j = 6480

Value of k = 3276

Value of i = 3

Value of i = 3

Value of i = 3

Value of i = 3

The following memory map will help you identify the relationships between i,j,k.

Location name       i.                                 j                            k

Value at location    4                              4096                      3276

Location number    6480                        3276                      7200

Observe how the variables i,j,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 to an int.

There is no limit on how far can we go on extending this defining. Possibly till the point we can comprehend it. And that point of comprehension is usually a pointer to a pointer. Beyond this, one rarely requires to extend the definition of a pointer. But just in case…..

Pointer jargon

Consider the following program fragment

int a=35;

int   *b;

b = &a;

Which of the following statements are correct?

Value at address contained in b is an int.
b is an int pointer.
b points to an int.
b is a pointer which points in the direction of int.

Well, all the statements are correct. All the statements are trying to establish the same fact, that since b contains an address of int, its an int pointer. Similarly had b contained an address of a float, it would have been a float pointer. With the same argument if we have three pointer variables first containing address of an array, second containing the address of a structure and the third containing the address of a function then it would be appropriate to call these as an array pointer, a structure and a function pointer respectively.

Char, int and float pointers

Consider the following program

main()

{

int i, *ii;

char c, *cc;

flaot f, *ff;

i=32;

c=’A’;

f=3.14;

ii=&i;

cc=&c;

ff=&f;

printf(“Value of i = %d\n”,*ii);

printf(“Value of c = %c\n”,*cc);

printf(“Value of f = %f\n”,*ff);

}

Output

Value of i = 32

Value of c = A

Value of f = 3.140000

Note that in the printf()s the addresses of char, int and the float all have been printed using the format specifier %u. Observe that though the

Page : 1 Next >>