Tuesday 13 August 2013

Pointers As I Understand Them

Pointers can be hard to work with. I still have a lot to learn, but here are somethings that have let me "wing it" for the moment. I'll try to explain what I know about pointers as simply as possible. I figure you'll need to use it for a while before you become familiar with them, if you aren't already.

A pointer stores an ADDRESS of another variable. So it points to that other variable.

Lets say your name is 'Zed'. You want to be a pointer. You must declare this by saying *Zed. From now everybody knows, and thinks of you as a pointer (Address Holder).

It's like if you held a piece of paper with a friend's address...you are the pointer...someone who doesn't know where your friend lived would come to you, you would read out the address and they would go there. Your friend is the value, you are the pointer.

*Zed' would indicate "The person whose address is with  Zed" . This means your friend. The program would find your friend in this case.
'Zed' indicates you. The program would find you in this case.


A pointer is declared like this: int *pointer_name

Whenever I see '*test' in a program I say to myself "The value at the address stored in 'test'".
When I see 'test' in that same program, if I know test has been declared as a pointer, I think "The address stored in 'test'"
If I see "&test" that would be the "address of the pointer 'test'", but it's unlikely I'll come across that unless there's a **test1 (Pointer to a pointer) involved, but that's another can of worms for another day.

From what I understand, a memory location has three characteristics:
1. The Address (Always Exists)
2. The Name (When we declare it, we give it a name)
3. The Value (Is a random number unless we assign it)

Example:

#include <stdio.h>

main()
{
    int test; //declare

    test=1; //assign
    printf("%i",test);
}

The program:
1. Declares an int naming it 'test'
2. Test is given a value of 1.
3. The value is printed.

For the duration of the program, the variable 'test' had three characteristics:
1. An Address
2. A name ('Test')
3. A value. (Random number that happened to be sitting in the memory location until we said test=1, from there on in, 'test' held the integer 1).

Lets take a look:

#include <stdio.h>

main()
{
    int test;

    printf("%i is the random number in 'test' before it is assigned\n",test);

    test=1;
    printf("%i is now the number we assigned to it",test);
}

We can view the address of a variable by adding '&' before it.

#include <stdio.h>

main()
{
    int test;

    printf("%i is the address of the variable 'test'\n",&test);
}

Notice in the printf statement, we didn't say 'test', rather we said '&test', so we got the address of the variable test.

We can store this address in a pointer:

#include <stdio.h>

main()
{
    int int1,*ptr;

    int1=5000;

    ptr=&int1; //give THE ADDRESS of int1 to the pointer. This MUST be done before the pointer is used

/**Here the program looks at the variable stored in 'ptr', the program knows that this is an address because
of the *, so it goes to that address, and displays the value there**/
    printf("Value at address ptr (*ptr) %i\n\n",*ptr);

/**Here the program looks at the variable stored in 'ptr' and shows it to us**/
    printf("Value stored in ptr (This will be the same as the address of int1) (ptr) %i\n\n",ptr);

/**The program goes to 'int1', gets the ADDRESS of the location and displays it. This location is an area in
your computers memory**/
    printf("Address of int1 (&int1) %i\n\n",&int1);

/**Finally, the program goes to 'int1' pulls out the value there, and prints it**/
    printf("Value stored in int1 (int1) %i\n\n",int1);

/**change the value at address ptr from 5000 to 3000. Here the program goes to
the address stored in 'ptr' (which is the location of 'int1') and puts a 3000 into it.
We can say the program puts 3000 into 'int1'. This is the same as saying int1=3000, except
here we send the program to ptr which has the address of int1, and then it comes to that address
and puts the value there.**/
    *ptr=3000;

    printf("Value at address ptr (*ptr) after *ptr is re-assigned %i\n\n",*ptr);
    printf("Value stored in int1 (int1) after *ptr is re-assigned %i\n\n",int1);
}



So simply remember:
A Pointer MUST be initialized (IE Initially, before it is used, It must be assigned an address otherwise your program will fail).

Whenever you see '*test' in a program say to yourself "The value at the address stored in 'test'".
When you see 'test' in that same program, and if you know test has been declared as a pointer, think "The address stored in 'test'"
If you see "&test" ,if you know test has been declared as a pointer, that would be the "address of the pointer 'test'".


________________________________________________________
EDIT:
WHY USE POINTERS?
This question bothered me for a long while a few months back before I used them. Why use pointers at all? Global variables (Variables declared outside any function) might suffice.
Since I'm still somewhat new to C, I use a lot of global variables in my big program (Yes, I only have one), but sometimes, using pointers seems to be the only way to keep things coherent and sensible.

I cannot show you a demo program to tell you how useful they are, it would still not convince an unbeliever :D, but trust me, you'll use them eventually....and thank God for them too. In fact, I don't think a person can retain much of this unless s/he is writing a program and suddenly finds him/herself unable to do something, then they see they can do it with pointers.
Interest can only be generated in something if it is needed.

Anyhow, here is a program that uses a couple of pointers sent to a function, if you really want to check it out:
http://zhukovc.blogspot.com/2013/08/draw-calendar-for-user-defined-month.html

I never learnt about pointers until I saw it can change values across functions, and that was exactly what I needed for a program I was writing. Then it seemed a little more interesting...and even easier...

No comments:

Post a Comment