Pointers in C - An Introduction

Pointers - Many beginners to C/C++ language are scared of this word. I used to be scared too. But let us jump into water. Come on, pointers won't bite!

Variables need to be stored in memory. These memory slots have addresses starting from 0 onwards. Each byte in the memory has an address 0,1,2,3 etc. C and C++ let you read the address of a variable.

If a is a variable, then &a is its address.

    int a;
    a=10;
    printf("%d\n",a);
    printf("%p\n",&a);

Line 4 in the code above prints the address of a in Hex.

lvalue and rvalue
  An expression which can appear on the LHS of an expression is called lvalue. Lvalue is something which has an address. 

      a = b+c;
      b+c = a;//wrong

Line 2 is wrong because b+c is not an lvalue. It is an rvalue. In fact = i.e. assignment operator in C. calculates the value on RHS and assigns this value to address of variable in LHS. b+c does not have an address. 

Pointers continued:
Now we can store this address of variable in another variable and this address holder is called a pointer.

             int a=10;
        p = &a;

p stores address of a viz p is pointer to a. 

Defintion of pointers:
Like all other variables, pointers must also be defined in the program (at the begining in c and before use in c++).

Syntax

   data-type *pointer-var;

data-type is any valid basic/compound data type or void. * indicates that our variable is a pointer.

e.g.
      int *ptr,*ptr2;
     char *cptr;
     double *dptr;

As you can see, the pointer definition includes the pointee type. ptr and ptr2 are pointers to integers. They store addresses of integers. cptr is char pointer and dptr is double pointer. 

Indirection operator : * is indirection operator also called value at operator or dereference operator. If ptr points to some variable num, then *ptr gives the value of num. & and * are complementary to each other. 

Next let us look at a complete program


#include<stdio.h>
int main()
{
     int a,*ptr1;                        
     char ch,*ptr2;
     int b;
     a = 10;
     ptr1 = &a;
    *ptr1 = 100;
     b = *ptr1;
     ptr1 = &b;
    ch = 'A';
    *ptr2 = &ch;
    (*ptr2)++;
    return 0;
}
    
 aaaaaaaaaaaaaa
ptr1 is integer pointer
ptr2 is char pointer


 ptr1 points to a
*ptr1 that is a is assigned to 100
b is assigned to *ptr1 i.e. 100
 Now ptr1 points to b
*ptr2 points to ch
ch is incremented to B



It is simple, right? 

Then why are people scared of pointers.

1> Uninitialized pointers are hazardous. May Will crash your program. Always make your pointer point to valid variable. 
2> A pointer pointing at 0 address or any invalid address crashes the program.It causes  The infamous segmentation fault

Null pointer : A pointer which points at nothing is called null pointer. A null pointer stores address 0. A good programming practice is until you know what to do with your pointer, store null in it and ALWAYS check if your pointer is null before your you use * operator on it. NULL is a macro for null pointer. Its value is 0

           int *ptr = NULL;//Now ptr is null pointer
       -----
       -----
       if(ptr==NULL)
       {
            printf("ptr is null. ");
       }
       else
       {
           printf("value at ptr is %d\n",*ptr);
       }


void pointer : Unlike null pointer, void pointer is a data type. It is a pointer which can store the address of any type of variable whether it is a char variable or  int variable etc. Whereas an int pointer (int *) can stored address of int only and a char pointer(char*) can store address of a char only.

      void *ptr;
      int a;
      char ch;
      ptr = &a;//valid
      *ptr=10;//incorrect
      *(int*)ptr=10;//correct
      ptr = &ch;//valid
      *(char*)ptr='z';


Many library functions use void pointers as their parameters in order to be flexible.
There is one restriction, though. A void pointer can not be dereferenced directly. You need to first type-cast it and then dereference it.

Why Pointers? 
Why do we need pointers at all? Because pointers are a the best way to access the hardware addresses. They let you manipulate an array in an easy way. Pointers let you modify the parameter to a function. And also, pointers are the only way to access dynamically allocated variables .



Comments

Popular Posts