January 18, 2011

Introduction
Pointers are a subtle concept to understand in itself. To deal with pointers, one need a deep understanding of their working. Pointers become even more brainteasing when they are used to access multidimensional arrays.

Assuming that the reader has basic understanding of pointers and arrays, I have written this article to fill in the gaps between the two. There are 5 code snippets in total. First one illustrates simplest pointer usage and the last one deals with dynamically allocated multidimensional arrays.

During this article, I have explained just enough theory through comments within the code. There is more code and less of text to let your brain exercise more and spoon fed less. Each of the Code Snippet is a complete C++ program in itself and can be executed as it is. I highly recommend to you to execute and play with these snippets.

So, go ahead. Stage is all yours! Comments and criticism are both welcome.

Basic Usage of Pointers
Following code snippet explains the basic use of pointers. It declares an integer variable a and an integer  pointer x.  Notice how x is made to point a and how it is used to access value stored in a.


Code Snippet #1:
#include<iostream>
using namespace std;

int main()
{
 cout<< "Understanding Pointers"<<endl;
 cout<< "----------------------\n"<<endl;

 int a =10;   // Declaration of an integer variable 
 int *x;   // Declaration of a pointer to integer 
 
 //Printing value of a.
 cout << "Variable a ..."<<endl;
 cout << "a =" << a << endl; // Output : a=10 

 //Assign pointer x to variable a
  x=&a;  
 //Now, x stores the address of variable a
 //In other words x is pointing to a

 //Lets print what is the value of x
 cout<<"\nx stores the memory location of variable a .."<<endl;
 cout<<"x =" << x << endl; 
 
 //Now to access the value stored in 'a', we have one more way - Use of DEREFERNCING operator *
 cout<<"\n*x is same as a. Use of dereference operator.."<<endl;
 cout<<"value pointed by x = *x = " << *x << endl;  
 return 0;
}

Output #2:
Understanding Pointers
----------------------

Variable a ...
a =10

x stores the memory location of variable a ...
x =0xbf990438

*x is same as a. Use of dereference operator ...
value pointed by x = *x = 10



Pointers and 1D Arrays
Following code snippet shows how a pointer can be used to reference any element of a Single Dimensional Array. It's interesting to see how this pointer is used to access all the members of array using pointer arithmetic .

Code Snippet #2:
#include<iostream>
using namespace std;

int main()
{
 cout<< "Understanding Pointers and 1D Arrays"<<endl;
 cout<< "-------------------------------------\n"<<endl;
 
 // Declaration of an integer array of size 10
 int arr[10]= {10,20,30,40,50,60,70,80,90,100}; 
 
 int *y; //Declaration of a pointer to integer 
 
 //Printing the array .
 cout<<"Original Array ..."<<endl;
 for(int i=0;i<10;i++)
  cout<< "arr[" << i << "]=" << arr[i] <<endl;

 //Lets make y to point to first element of the array
 y= &arr[0];

 //For accessing arr[0], we can use *y. Notice, both are same..
 cout <<"\nComparison between arr[0]and *y ..." << endl;
 cout << "arr[0]="<< arr[0]<<endl; //Output : arr[0]=10
 cout << "*y    ="<< *y<<endl;     //Output : *y    =10    
    
 // Funda : When an array is allocated, contiguous memory 
 //         cells are allocated.
 // So, if y points to arr[0], y+1 will point to arr[1], y+2 
 //         will point to arr[2] and so on ..
 // Hence y+i points to y[i] i.e. *(y+i) is same as y[i]
 
 //Lets try this out
 cout<< "\nPrinting array using pointers ..."<<endl;
 for(int i=0;i<10;i++)
  cout<< "*(y+" << i << ")=" << *(y+i) <<endl;
 
 // Funda : array's name can be used as a pointer to first 
 //         element of array. For exp:
 // arr points to arr[0] i.e. arr =&arr[0] i.e. *arr=arr[0]
 //Lets try this out
 cout << "\nThe two values below should be same ..." << endl;
 cout << "arr[0]="<<arr[0] <<endl;  
 cout << "*arr  ="<<*arr   <<endl;
 
 
 // By pointer arithmetic, we can conclude that *(arr+i) is 
 //         same as arr[i]
 cout<< "\nPrinting array using arr pointer ..."<<endl;
 for(int i=0;i<10;i++)
  cout<< "*(arr+" << i << ")=" << *(arr+i) <<endl;
}
 
Output #2:
Understanding Pointers and 1D Arrays
-------------------------------------
 
Original Array ...
arr[0]=10
arr[1]=20
arr[2]=30
arr[3]=40
arr[4]=50
arr[5]=60
arr[6]=70
arr[7]=80
arr[8]=90
arr[9]=100
 
Comparison between arr[0]and *y ...
arr[0]=10
*y    =10
 
Printing array using pointers ...
*(y+0)=10
*(y+1)=20
*(y+2)=30
*(y+3)=40
*(y+4)=50
*(y+5)=60
*(y+6)=70
*(y+7)=80
*(y+8)=90
*(y+9)=100
 
The two values below should be same ...
arr[0]=10
*arr  =10
 
Printing array using arr pointer ...
*(arr+0)=10
*(arr+1)=20
*(arr+2)=30
*(arr+3)=40
*(arr+4)=50
*(arr+5)=60
*(arr+6)=70
*(arr+7)=80
*(arr+8)=90
*(arr+9)=100

Pointers and 1D Dynamically Allocated Arrays
Following code snippet shows how memory is allocated dynamically and assigned to a pointer. Again pointer arithmetic is used to access all the elements of the array. There are two ways to access the array elements. You should be able to understand both of them easily.

Code Snippet #3

#include<iostream>
using namespace std;

int main()
{
 cout<<"Understanding Pointers & 1D Dynamically Allocated Arrays"<<endl;
 cout<<"----------------------\n"<<endl;

 int* c;  // Declaration of pointer to integer
 
 //Dynamic allocation of an array of size 10
 c = (int *)malloc(10 * sizeof(int));
 
 //A block of memory is allocated by malloc() and is now pointed by pointer c.
 
 //Initializing Array using pointer c to access the array 
 for(int i=0; i<10;i++)
   *(c+i)=i*100;

 //Printing array using pointer c to access the array 
 cout << "\nPrinting array using pointer c to access the array ..." << endl;
 for(int i=0; i<10;i++)
 printf("*(c+%d) = %d\n",i,*(c+i));

 //Funda***
 //In code snippet #2, we used array's name i.e. "arr" as a pointer. The reverse is also true.
 //c points to the first element of this array. 
 //We can use c as if it is the name of array i.e. by using c[0], c[1] etc to access the array  
 
 
 //Printing array using c as name of the array
 cout << "\nPrinting array using c as name of the array ..."<<endl; 
 for(int i=0; i<10;i++)
  printf(" c[%d] = %d\n",i,c[i]);
 
 return 0;
}


Output #3:
Understanding Pointers and 1D Dynamically Allocated Arrays
----------------------


Printing array using pointer c to access the array ...
*(c+0) = 0
*(c+1) = 100
*(c+2) = 200
*(c+3) = 300
*(c+4) = 400
*(c+5) = 500
*(c+6) = 600
*(c+7) = 700
*(c+8) = 800
*(c+9) = 900

Printing array using c as name of the array ...
 c[0] = 0
 c[1] = 100
 c[2] = 200
 c[3] = 300
 c[4] = 400
 c[5] = 500
 c[6] = 600
 c[7] = 700
 c[8] = 800
 c[9] = 900



Pointers and 2D Arrays
Following code snippet illustrates how  to declare and access a 2D array. Underneath 2D Array lies a single dimensional array. You will get be sure of this after playing with the following piece of code.




Code Snippet #4

#include<iostream>
using namespace std;

int main()
{
 cout<< "Understanding Pointers and 2 D Arrays"<<endl;
 cout<< "----------------------\n"<<endl;

//Declaration of a 2D Array.
int tab[3][5];
//Total space required : 3*5 * sizeof(int) = 15 * sizeof(int) 
//Funda : Since the amount of required space is known by compiler, contiguous 15 memory cells are allocated here.   
//Hence the case is similar to a 1 D Array of size 15. Lets try this out!

//Array initialization using array name 
for(int i=0; i<3;i++)
 for(int j=0; j<5;j++)
   tab[i][j]=i+2*j;

//Print array using array name 
cout << "\nPrint array using array name ..."<<endl;  
for(int i=0; i<3;i++)
 {
  for(int j=0; j<5;j++)
   printf("%2d ",tab[i][j] );
  printf("\n");
 }

//Print array using a pointer. Proof of 1 D array being allocated
cout << "\nPrint array using a pointer. Proof of 1 D array being allocated ..." << endl;     
int *tptr;
tptr = &tab[0][0]; // pointer tptr points at first element of the array. 

for(int i=0; i<15;i++)
 printf("%d ",*(tptr+i) );
tptr = &tab[0][0];
cout << "\nNotice that array is printed row by row in a linear fashion."<<endl;
 return 0;
}

Output #4:
Understanding Pointers and 2D Arrays
----------------------


Print array using array name ...
 0  2  4  6  8 
 1  3  5  7  9 
 2  4  6  8 10 

Print array using a pointer. Proof of 1 D array being allocated ...
0 2 4 6 8 1 3 5 7 9 2 4 6 8 10 
Notice that array is printed row by row in a linear fashion.



Pointers and 2D Dynamically Allocated Arrays
Following code illustrates the concept of 2D arrays using dynamic allocation. An array of pointers is used to hold n 1D arrays leading to one 2D array. Again to access the array elements, there are multiple ways. Check out what they are ..


Code Snippet #5
#include<iostream>
using namespace std;

int main()
{
 cout<< "Understanding Pointers and 2D Dynamically Allocated Arrays"<<endl;
 cout<< "----------------------------------------------------------\n"<<endl;

 //AIM :  To create a 2D array with 7 rows and 10 columns
 
 //If we have one pointer, we can use malloc() and allocate memory for 1 array.
 //So, for n arrays, we would n pointers. Notice that a 2D array simply a collection of 1D Arrays.
 //Hence to implemet a 2d Array, all I need is a "Array of pointers". Each of whose element will point toa 1 D Array
 
 
 //"Array of Pointers"
 //Now we need a pointer which will point to this 'Array of Pointers' 
 //We declare pointer to pointer like this ...
 int ** table; 
  
 // Allocation of "Array of pointers"
 table = (int **)malloc(7*sizeof(int *));

 //Now allocatinc an array of integers for each of these 7 pointers ... 
 for(int i=0; i<7;i++)
  {
   *(table+i)= (int *)malloc(10*sizeof(int));  // Option 1 
   //table[i]= (int *)malloc(10*sizeof(int));   // Option 2  ... you can use either of these two statements.
  }
 
  //Note : *(table+i) is exactly same as table[i]  --- Prove this!!
 cout << "Pointer to i'th row = *(table+i) <=> table[i] "<<endl; 
 
 //Initialization of 2D Array 
 for(int i=0; i<7;i++)
  for(int j=0; j<10;j++)
   *(*(table+i)+j) = i+j;

 //Note : *(*(table+i)+j) is exactly same as table[i][j]    --- Prove this!!
 cout << "\nValue of element @ i'th row & j'th column = *(*(table+i)+j) <=> table[i][j] "<<endl; 
 
 //Lets check out the equality of above 2 expressions ...
 //Printing 2D Array by using pointers
 printf("\nPrinting 2D Array by using pointers. *(*(table+i)+j)\n");
 for(int i=0; i<7;i++)
 {
  for(int j=0; j<10;j++)
   printf("%2d ",*(*(table+i)+j) );
  printf("\n");
 }

 //Printing 2D Array by using easy to understand names
 printf("\nPrinting 2D Array by using easy to understand name. table[i][j]\n");
 for(int i=0; i<7;i++)
 {
  for(int j=0; j<10;j++)
   printf("%2d ",table[i][j] );
  printf("\n");
 }
 return 0;
}



Output #5:
Understanding Pointers and 2D Dynamically Allocated Arrays
----------------------------------------------------------

Pointer to i'th row = *(table+i) <=> table[i] 

Value of element @ i'th row & j'th column = *(*(table+i)+j) <=> table[i][j] 

Printing 2D Array by using pointers. *(*(table+i)+j)
 0  1  2  3  4  5  6  7  8  9 
 1  2  3  4  5  6  7  8  9 10 
 2  3  4  5  6  7  8  9 10 11 
 3  4  5  6  7  8  9 10 11 12 
 4  5  6  7  8  9 10 11 12 13 
 5  6  7  8  9 10 11 12 13 14 
 6  7  8  9 10 11 12 13 14 15 

Printing 2D Array by using easy to understand name. table[i][j]
 0  1  2  3  4  5  6  7  8  9 
 1  2  3  4  5  6  7  8  9 10 
 2  3  4  5  6  7  8  9 10 11 
 3  4  5  6  7  8  9 10 11 12 
 4  5  6  7  8  9 10 11 12 13 
 5  6  7  8  9 10 11 12 13 14 
 6  7  8  9 10 11 12 13 14 15 

No comments:

Post a Comment