Pointer Reloaded


Pointers are  considered one of the most confusing concepts in c , so I would try to explain it in a more detail and vivid way ,

Ok first of all let us consider a stack of 10 boxes and each box has a location in the stack like 1st box , 2nd box up to 10th box , now let us think that we have stored an integer in each of the box like 99 , 87 , 76 and so on as shown in the figure below

 
Now let us give a name to the box number 5 and called it as “x” , so basically we have done this

X = 2

And this x = 2 is in which box ?

It is in 5th box , that will be the address of that box

Now when we say to someone about “x” , what do we mean by “x” ?

We mean the value stored in x that will be in our case is 2 , so it will be like this

X = value stored in x

And if we say what is the address of “x” then what will we say ?

5th box is the address of x , which in a c language syntax we can write as

&x  =  5th box  =  address of x

Always remember that the ampersand sign “&” means address of something

Now if we  ask , what is the content of the 5th box ?

The answer would be 2 , but instead of asking directly that what is “x” , we are indirectly asking the value of x from the address point of view or in our example box position , in c language this is represented as

*address of the box number 5  = * 5th box , both these expressions will give the same value below

*address of the box number 5 = x = 2

So we see that it is possible to get the address of a value and also user this address to access the value itself 

&x = address of x
*address of x = contents of x

As seen in the figure above all the address of the boxes can be accessed using the “&” sign and all the contents of those addresses can be accessed using the  “*”  symbol
So now we can say

X = 2

&X = address of X

*address of x = 2

In a programmatic form the above lines can be represented as

main()
{

 int x = 2;

 printf("value of x is %d\n",x);  //display the value of x that will be 2

 printf("address of x is %d\n",&x); //display the address of x that will be a long number

 printf("contents in the location %d is %d",&x,*(&x));
//display address of x and then the contents in that address , that will be 2

 getch();
     
}

See in the last printf statement we use  “*(&x)” which is nothing but in English is
“the contents of the memory location whose name is x “ and that is 2

This is the concept of pointers  , so if you think you are done  in understanding pointer concepts then answer me this

We know that from the above example

X = 2

&X = address of X

*address of x = 2

Now if I ask you what will be the answer to the following expression

*X   =  ? ? ?

Can you answer this ,

I can give you a hint  , , , “to answer this you have to look at the box diagram above”

Be honest with yourself

Ok let me give you the answer , it will be

*X = 87

If you have got the answer then you got it but if not then let me explain it to you
*X means in English  “the contents of the box having the address  x” and in our case x is 2 , so the expression means  *2  or we can say  “the contents of the box at second position” that is in our case is  87 , hope you got it this time but if not then my next example might help you


 Instead of thinking all about these memory and memory addresses let us think about a magic show and the name of the magic show is “main function show” , there are 6 chairs in the magic show for audiences to watch and because of rain 5 of them were unable to attend the show , so 5 chairs are empty but Mr. Cat who likes magic show very much was present at the show and waiting for the show to start as we can see in the figure below








Now let us imply the knowledge from the first example (box example) and see what will be the results for each expression

& Mr. Cat = address of Mr. Cat , that will be 2nd Row , 2nd Seat

& Mr. Cat  =  2nd Row , 2nd Seat

And if we use the  “*” operator then this will be

*  2nd Row , 2nd Seat  = Mr. Cat

This is the same thing as saying

&X = address of X and * address of X = X  

This is the concept of pointers , hope this time it is clear with you , but how to use pointers in a actual c program , let me give you  a actual c program for this

main()
{
int x = 100;

int *pointer;

pointer = &x;

printf("Address of X is %d\n",pointer);
printf("Pointer is pointing to x which contains  %d",*pointer);

getch();
}

Hmmmm its look different but trust me it implies the same logic that we have studied so far , let me explain it line by line

int x = 100;  = this is not very difficult to get , we declare a variable called X which is of integer type and set the value as 100

int *pointer; =  this looks different , but let me explain , now if we remove the “*” sign from the expression what will we get , something like this int pointer  , but this is nothing but a integer variable declaration , but the adding of the “*” symbol before the pointer word makes it a special variable , a variable that have the ability to store memory address of other variable and in our case an integer variable , int *pointer  means a pointer variable of integer type , if there was flaot instead of int then it will mean that the pointer can store address of a variable of float type
so to sum it up here we declare a special variable that have the ability to store addresses of other variables

pointer = &x; = in the code above  we declare a variable that can store the address of other variable , but we have not specified which address to store , In this code we specify the pointer to store the address of x , &X which is the address of x is now stored in the pointer which is a special type of variable which can store addresses

printf("Address of X is %d\n",pointer); = we display the address of X which is stored in the special variable pointer

printf("Pointer is pointing to x which contains  %d",*pointer); = now if we want to display the value of x indirectly through the use of the pointer we use *pointer which in English means show the contents of the variable whose address is stored in the  pointer

This is how pointers are used in actual c programming  , next I am going to explain the uses of pointer or the main use of pointer


Function parameter = whenever we pass something to a function we actually are not passing the original value we are just passing a copy of the original value , which sometimes becomes a problem and also consumes more memory , if our program is small then it might work well but in case of large scale program this would create a bug in the program , so we use pointers which gives us the ability of manipulating the original value 

To better get it , let us see an example

void function_no_pointer(int x)
{
x = x + 1;
printf("Inside Function function_no_pointer %d \n",x);
}

 void pointer_function(int *x)
{
*x = *x + 1;
printf("Inside pointer_function %d\n",*x);
}

main()
{
    
     int xM = 5;
     printf("xM originally was %d\n",xM);
     function_no_pointer(xM);
     printf("Inside main function %d \n\n\n",xM);
    
    
     int yM = 88;
     int *ptr;
     ptr = &yM;
     printf("yM originally was %d\n",yM);
     pointer_function(ptr);
     printf("Inside main function %d \n",yM);    
    
     getch();
     
}

This is a very simple program which just calculate the next number for variables xM and yM which we have already defined as 5 and 88 , we pass these values to two functions which just adds 1 to them and display the result

Now notice that inside the main function we have declared xM as 5 , we then pass it to function called  “function_no_pointer”  which just adds 1 to the value of xM , we also display the result from inside this function which is 6 and also from inside main function , but inside main function xM is still 5 not 6 because we have just incremented a copy of xM,  but the original xM is  intact , so if we want to edit the original variable we have to use pointers as in the second function

Now we have declared a second variable called yM and also a pointer ptr which contains the address of yM , now we pass ptr to a function caller “function_pointer” and do the calculation from the address point of view , now we display the result from inside this function and also from inside the main function and in both case the result is  89 , so we have been able to change the original value this time by using pointers


Function pointers = we can even pass a function as a pointer , it is same as  regular variable pointer . Let us see an example to better understand this concept

int add_function(int x , int y)
{
    return x + y ;
}

main()
{

 int z = 0;

 int (*function_pointer)(int , int);

 function_pointer = &add_function;

 z = (*function_pointer)(5,4);

 printf("%d",z);

 getch();    
}

First we have a function called “add_function” which accepts two integers and returns the addation of the two integers , now inside the main function we declare a function pointer like this

int  ( *function_pointer ) ( int , int ) ;

as we can see this is a function pointer which accepts two integers and return an integers , notice the “*” operator before the name “function_pointer” which signifies that this is a function pointer , now this function pointer is not pointing to any function so to do that we write the following code

function_pointer = &add_function;

from the above code of line we now store the address of the “add_function” function on our function pointer or initialized our function pointer

z  =  ( *function_pointer ) ( 5 , 4 ) ;

after declaration and initialization of our function pointer we can use our function pointer to actually do something , here we are passing two integers to the “add_function” by using function pointers and storing the result in the variable called “Z” and displaying the result

This is a very simple example of how function pointers can be used in our programs



Pointers and structures = structures are very important part of c programming which can be used for user defined data types , now let us say we have created a structure , fill the structure with data and  now we pass the structure to a function , So in this case what happens is that that a copy our structure is made and this copy is passed to the function , In case of large scale structures it will consume more memory and also will make our program slow , So to handle this situation instead of passing a whole structure  we pass a pointer pointing to the structure , let us see an examples of it

struct my_structure
{
char first_name[20];
char last_name[20];
int age;
int id_number;
};

struct my_structure my_s;

display_result(struct my_structure *pointer)
{
printf("Information in my_structure is \n%s \n%s \n%d \n%d \n\n\n",
pointer->first_name,pointer->last_name,pointer->age,
pointer->id_number);


      strcpy(pointer->first_name,"Agent");
      strcpy(pointer->last_name,"007");
      pointer->age = 99;
      pointer->id_number = 99999999;
     
printf("Information in my_structure is \n%s \n%s \n%d \n%d ",
pointer->first_name,pointer->last_name,pointer->age,
pointer->id_number);

}

main()
{
      struct my_structure *structure_pointer;
      structure_pointer = &my_s;
     
      strcpy(structure_pointer->first_name,"James");
      strcpy(structure_pointer->last_name,"Bond");
      structure_pointer->age = 70;
      structure_pointer->id_number = 12345678;
      display_result(structure_pointer);
      getch();     
}

In this example we first declare a structure called “my_structure” having the appropriate fields and also “my_s” of “my_structure” type
Now we have a function called “ display_result” which accepts a structure pointer type of type “my_structure”

Now inside main function we declare a structure pointer

struct my_structure *structure_pointer;

and assign this pointer to “my_s” of “my_structure” type

structure_pointer = &my_s;

now we use structure pointer to assign values to the fields of “my_structure” and pass “structure_pointer” to “display_result” function which accepts a structure pointer as its parameter
inside “display_result” we display the fields and also assign new set of values to “my_structure” through the use of pointers


pointers and array = we can use array and pointers side by side with each other or replace arrays with pointers or pointers with arrays , but  they have to be declared first , One point to remember is that the size of a pointer is not the actual size of the array because pointers only store the address of the array which is in a 32 bit system is 4 byte

following example can help us to understand the use of pointers and array

main()
{
 int i;
 int array[] = {1,2,3,4,5};    
 int *pointer;
 pointer = &array;

 for(i=0;i<5;i++)
 {
 printf("%d\n",pointer[i]);
 }

getch();

}
One point to remember is that when we assign a pointer to an array we actual store the address of the first index of the array in the pointer

Pointer to pointer = it is possible to assign a pointer to a pointer , which means we have a pointer which stores the address of a variable and another pointer which stores the address of that pointer , but I will not only show you pointer to pointer but pointer to pointer to pointer

main()
{

 int x = 100;

 int *p1;

 int **p2;

 int ***p3;

 int  *pt1,*pt2,*pt3;

 p1 = &x;

 printf("address in p1 is %d\n\n",p1);

 p2 = &p1;
 printf("address in p2 is %d\n\n",p2);

 p3 = &p2;

 printf("address in p3 is %d\n\n",p3);

 printf("content of pointer p1   : %d\n",*p1);
 printf("content of pointer p2   : %d\n",*p2);
 printf("content of pointer p3   : %d\n",*p3);

 pt1 = p1;
 printf("\n\naddress in pt1 is %d\n",pt1);

 pt2 = pt1;
 printf("address in pt2 is %d\n",pt2);

 pt3 = pt2;
 printf("address in pt3 is %d\n",pt3);

 printf("\n\ncontent of pointer pt1   : %d\n",*pt1);
 printf("content of pointer pt2   : %d\n",*pt2);
 printf("content of pointer pt3   : %d\n",*pt3);
 getch();
}

In the above example  we first declare a integer variable “X”  and then three pointers p1 , p2 , p3 , notice the increasing “*” symbols with pointers , which signifies that they are pointer to pointer and pointer to pointer to pointer

Now we assign the address of x in p1 and display the address , then we pass the address of p1 into p2 and display the address and finally we pass the address of  p2 into p3 and display the address , we also display the contents of the pointers or the thing the pointers are pointing to ,  for p1 it will be the value of x but for p2 and p3 it will be the address of the former pointer

We also declare three pointers pt1 , pt2 and pt3 . Pt1 stores p1 , then pt2 stores pt1 and finally pt3 stores pt2 and display their address and contents

This might look confusing , so I have included a screenshot of the output , so that you can relate it with the program



Coming soon




No comments:

Post a Comment