The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as
well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct. Donald E. Knuth

Pointers in C

Pointer is one of the most fascinating aspects of C programming language. Mastering the clever use of pointers is a gateway to become an expert C programmer. For the beginners, it is considered to be the most difficult concept to understand but it is just a myth which will be broken as you go ahead with this tutorial. Learning pointers is fun and it lets you realize and appreciate the power of C language. Some of the operations like dynamic memory allocation ( discussed later ) is not possible without pointers. Let's start exploring pointers.

What is a Pointer ?
Consider the following declaration :

int x = 13;

This declaration reserves a space of 4 bytes (integer) in memory. That memory location is named ' x ' and a value 13 is stored there. Now, every memory location has an address. Pointers are a means to store and access the address of this memory location. In simple words, a pointer variable stores the address of another variable. Note that every address is represented by a number in hex notation.
Following program demonstrate the concept :

/*
 * Demonstration of pointer concept
 */
#include <stdio.h>

int main() {
   int x = 34; /* declared and initialized a variable of type integer */
   int *ptr;   /* declared a pointer variable of type integer */
   ptr = &x;   /* assigned the address of 'x' to 'ptr' */

   /******** Access the address of variable 'x' *********************/
   printf("Address of variable 'x' is %p\n", ptr);
   printf("Address of variable 'x' is %p\n", &x);
   /*****************************************************************/

   /******** Access the value stored in variable 'x' ****************/
   printf("x = %d\n", x);        // usual manner
   printf("x = %d\n", *ptr);     // print value at 'ptr'
   printf("x = %d\n", *(&x));    // print value at 'address of x'
   /*****************************************************************/
   return 0;
}

In the above program, we declared a pointer variable ( ptr ) of integer type. This indicates that this variable can store the address of an integer variable only. Next we store the address of another variable ( x ) in the pointer variable ( ptr ) using ampersand ( & ) operator. Next set of statements show different ways of knowing the address and value of variable x.

Pointer to a Pointer
A pointer variable stores address of another variable. It can even store the address of a pointer variable. This is where the concept of pointer to pointer comes into play. Following program demonstrates the concept :

#include <stdio.h>

int main() {
   float x = 17.542317;
   float *i;  /* declare a pointer variable 'i' of type 'float' */
   float **j; /* declare a pointer to a pointer variable */
   i = &x;    /* 'i' stores the address of a normal variable 'x' */
   j = &i;    /* 'j' stores the address of a pointer variable 'i' */

   printf("Address of 'x' is %p\n", i);
   printf("Address of 'x' is %p\n", *j); /* value at 'j' is 'i' */
   printf("Address of 'i' is %p\n", j);

   printf("x = %f\n", x);
   printf("x = %f\n", *i);    /* value at 'i' is x ( 17.54 ) */
   printf("x = %f\n", **j);   /* value at value at 'j' */

   return 0;
}

We just need to remember that ' & ' denotes address of a variable and ' * ' denotes value at a particular address.
A statement like int ***k is also legal. It simple means it stores the address of pointer to a pointer variable. From the above program, j = &i. Similarly, k = &j.

void type Pointer
An integer pointer (int *ptr) can store an address of integer type variable (int x) only. Similarly, a floating point ptr (float *ptr) can store an address of float variable only (float x). This is valid for all data types except void which can store address of a variable of any data type. Following program illustrates the use of void type pointer :

#include <stdio.h>

int main() {
   int x = 27;
   char ch = 'J';
   void *ptr;
   ptr = &x; /* ptr points to address of 'x' i.e holds the address of 'x' */
   printf("Address of 'x' : %p  and Value of 'x' : %d\n", ptr, x);
   ptr = &ch; /* ptr now points to address of 'ch' */
   printf("Address of 'x' : %p  and Value of 'x' : %c\n", ptr, ch);
   return 0;
}


NULL Pointer
A pointer variable can be assigned a value NULL indicating that the variable doesn't point to any memory location. For e.g, int *ptr = NULL; The statement printf(" %x ", ptr); would print 0. So, ptr is a NULL Pointer.

Pointer Arithmetic
A pointer variable stores an address which is just a numeric value. Thus we can perform airthmetic operations on it similar to the way we do on normal variables. There are four arithmetic operators that can be used on pointers ++, --, +, - . Following program demonstrate pointer arithmetic operations :

/*
 * Pointer Arithmetic operations
 */

#include <stdio.h>

int main() {
   int x = 27; /* size of x is 4 bytes */
   int *ptr; /* pointer variable of type integer */
   ptr = &x;
   printf("ptr : %p\n", ptr);
   ptr++; /* ptr gets incremented by 4 bytes */
   printf("After Incrementing :- \nptr : %p\n", ptr);
   ptr = ptr - 2; /* ptr gets decremented by 8 bytes */
   printf("After Decrementing :- \nptr : %p\n", ptr);
   return 0;
}

Suppose x is stored in memory location k i.e value stored in x is k. If we do x++, x now points to (k + 4) since at location k, an integer type variable is stored whose size is 4 bytes.

If you haven't realized yet, you have already learnt the basics of pointers. Now it's time to apply the fundamentals to solve problems. Well, pointer application will be introduced as and when required in the tutorial. We will end this topic by introducing one famous application of pointers.

Function Pointers
We have seen that pointer variable points to a memory location of another variable. A function pointer points to the memory location of an executable code i.e it can store the address of a function and can be used to invoke the function it points to. Using function pointers, we can select which function to invoke at run time depending on some values. In usual technique, functions to be invoked at particular portion of the program is decided at compile time. Following program demonstrates the use of function pointers :

/*
 * This program demonstrates function pointers
 */

#include <stdio.h>

int add (int, int);
int subtract (int, int);

/* adds two numbers */
int add ( int a, int b ) {
   return (a + b);
}

/* subtracts 2nd no. from 1st */
int subtract ( int a, int b ) {
   return (a - b);
}

int main() {
   int x = 5, y = 2;
   int sum, diff;

   /* declare a function pointer 'operate' with two arguments
    * It can point to any function with two integer type arguments
    * and return type 'int' 
    */
   int (*operate)(int, int);

   /* decide at run time which function to call (add or subtract) */
   operate = &add; /* 'operate' points to function 'add' */
   sum = operate(x, y); /* call add() */
   printf("Sum : %d\n", sum);
   operate = &subtract; /* 'operate' points to function 'subtract' now */
   diff = operate(x, y); /* call subtract() */
   printf("Difference : %d\n", diff);

   return 0;
}

We can observe that at run time, either the function add ( int, int ) or subtract ( int, int ) can de selected using the function pointer ( *operate )( int, int ). Also the statement operate = &add; can be written as
operate = add; i.e ' & ' is optional here.

Back | Next