Thursday, 17 March 2016

Pointer in C - Made Easy - Part 02

Hope you still remembered, what we learned in Part-1.

If not, please go back and read once again before starting reading this.



Now let’s try to understand the pointers using the functions.

main()
{
int sum;
sum = 21;
func(n);
}

func(x)
int x;
{
        printf("%d.\n", x);
}

What do you expect from above program?

Of course it will print the value of x which is being passed from main () to func (). So remember, it is a “Pass by Value” example.

Above program passes an integer "by value" from one function to another. Means, it makes a copy of the value of sum and copies the value of sum into the new variable x! Nothing changes at the location of sum.

              |---|
 0x1100  |21 |  sum is an integer
              |---|
 0x1104  |21 |  x is another integer
              |---|

Another way of saying that when we are talking about x, we are storing a value “21” in x and the location of x is 1104,

If we change anything at that location 1104, it will only change there and this will not affect the location 1100. Simply, if we change x, it will not change sum. This is simple, right?

Now one question… If you want that func() should modify the value and pass these changes also to main (). Means the changed value should be available in main() also.

How we can do that? Don’t get it complicated. Instead of passing the value, if we directly pass the memory location then??? Think about that.

Then the value at the memory location will be changed. This is called in C as “Pass by reference”. Let’s see it by an example.


main()
{
int sum;

        sum = 21;
        fuc(&sum);
}

func(x)
int *x;
{
        printf("%d.\n", *x);
        *x = 51;
}

Try to understand what we did above?

We have passed the address of sum (&sum) instead of passing the sum. Hope you still remember (we learned it in part-1)that &sum is address of sum.

Now since we are passing an address (memory location) to func(), x should be capable of handling a memory address, that means it should be a pointer.

Remember how we define a pointer, of course, int *x

Actually, this is still passing by value, but the value being passed is the memory address, not the number.

              |----|
 0x1100  | 21 |  sum is an integer
              |----|
 0x1104  |1100|  x is a pointer to int
              |----|

Now in func() when we make use of *x, we are referring to the value at location 1100.  This is the location of sum and in this example the value at that location is 21.

After the assignment "*x = 51;", this is what we have:

              |----|
 0x1100  | 51 |  sum is an integer
              |----|
 0x1104  |1100|  x is a pointer to int
              |----|

So what happened? By saying “*x=51”, we have instructed the program to assign the value 51 at memory location being held by x. (Note it is int *x=51, not x=51)

x still points to location 1100, but we have changed the value of the object (which is sum) at that location.


Let me ask you something which looks complicated.
What if, I write "*x=**ptr++"

I know, you didn’t like it at all.

OK, Let’s make a table then:

              |----|  Here is a memory location with initial value 0.
 0x1100  |   0|  no variable name
              |----|
 0x1104  |  12|  here is a value, in memory location 1104.  No variable name.
              |----|
 0x1108  |1104|  Here is an int pointer, pointing at the previous location.
              |----|
 0x111c   |1108|  here is ptr, a pointer to int pointer. Means ptr is a pointer
              |----|  and holds address of pointer. Here it is holding the address      
                of the pointer at 1108

 0x1120  |1100|  here is x, a pointer.  It is pointing to the location 1100
              |----|


First let's see how we declared  ptr and x:

int *x;      /* pointer to int */
int **ptr;   /* pointer to pointer.  
              The subordinate pointer (the pointer to which the ptr  points
                           to, is a pointer to int.*/

Now we know what "*x" means.  It means, "the value of location 1100."
Now we know what "*ptr" means, "the value of location 1108".
Now that value is another address (1104) 

Now "*x = **ptr" says, "this int at 1100 (means x) gets the value of that int at 1104."

And what does "**ptr++" mean?   This is equivalent to:  *( *( ptr++ ) )
Or, "pointer to pointer to int, and finally  ptr has been incremented once we dereference that statement.  But we looked where it was pointing before it got incremented.

Note:
These all technical articles are dedicated to my teachers, my seniors, colleagues, internet bloggers, online technical material, reference books from where I learned all these. If anything is replicated anywhere, proper credits are understood to be given.

No comments:

Post a Comment