Pointers [C++][Coding]

Started by: Automaton | Replies: 2 | Views: 1,894

Automaton
2

Posts: 4,779
Joined: Nov 2007
Rep: 10

View Profile
Sep 26, 2008 10:39 PM #262458
POINTER TUTORIAL [C++]

Sorry for the lack of tutorials, but I really haven't been arsed to make any lately :)

First things first, this is not for beginners in C/C++. i.e. If you've only just read my other "hello world" tutorial, you won't understand this. This is generally for people who have a respectable understanding for program flow, functions, arrays etc. So if you don't know this stuff, there are plenty of sites to learn it quick and easy. The reason I'm not doing a tutorial on those, is because they're pretty much easy enough to learn for yourself. When you get to pointers, that's when you can start to get confused.

Second things second, this tutorial is not strictly directed at C++ programmers, as all the code is easily converted to C, however, all the code will be written in C++, as it's my preference.

And thirdly, any comments to help improve this tutorial are welcome, and I will try to update the tutorial to help as soon as possible, or as soon as I can be bothered. Now, on to the tutorial...

[SIZE=3]WHAT ARE POINTERS
[SIZE=2]Obviously, the first thing someone will ask is: "what is a Pointer?". Put Quite simply, a pointer is a variable that points to other data. That's what most people would say, and quite respectively, thus the name "pointer". However, this definition in itself can cause confusion. This is because it doesn't actually "point". In fact, the variable contains an address. This is the address in your computer's memory where the data it is "pointing" to is stored. This address is usually written in hexadecimal.

So first, a word on your computer. Each computer can be thought of as a shoe store. Except that your computer could hold billions of billions of shoes. In a shoe store, each pair is held in little "cubby holes". This in turn can be seen as a single cell in your PC. This cell has an address (a bit like the row/column number in the shoe shop) which is written in hex, and in that cell, instead of there being a pair of shoes, there is whatever data has been assigned to that cell. When you make a variable and initialise it, that variable is given a cell to stay in at run-time. So if you created an int variable, that variable would be stored in an unknown cell at runtime. I think that's all I want to go into about the physical side of things for the moment, as I don't want anyone's brain to explode.

Now, a pointer takes up 32 bits in a 32 bit system, and 64 in a 64 bit system (duh). A pointer holds the address of another variable, so in turn acts as that variable. So if you have a pointer called "pointer", and a variable called "variable", and you made the pointer "point" to the variable, "pointer" would act as "variable". That is the fundamental thought behind pointers, but we will see later that this is not exactly the case.

[SIZE=3]USING POINTERS
[SIZE=2]To declare a pointer, you do so exactly like you would with another variable. However, the only thing you do different is add a star before it. Not too hard huh? here is an example:

int* pointer; //creates a pointer
int *pointer; // also creates a pointer

You can see that it doesn't matter where the star is, as long as it's before the variable name, and after the variable type. I prefer the first method, for some odd reason. You may not.

Now that pointer is pretty useless stuck there by itself, so we need to give it something to point to. Now, if you've been following me, you should already know, or think that this is how you would assign it something to point to:

int variable = 2;
int* pointer = variable;

That is totally logic, except for one crucial thing; a pointer points to the address of a variable, not the variable itself. Imagine it like this.

(pointer)--| (variable)
"address" |---------------------------->"address"

As you can see, it doesn't point to the variable, but the "cell" it is stored in. (Imagine it pointing to the cubby hole in the shoe shop, instead of the shoes themselves).
Now, we can make a pointer point to a variable's memory cell by placing a "&" (andersand) sign in front of the variable. This andersand sign before the variable says it wants the location of that variable, rather than the variable itself. Take a look at this code:

int variable = 2;
cout<<&variable;

this would print out the memory address of the variable, as the andersand preceeding it tells the compiler it wants the address of the followind variable. This code would output a hexadecimal address to the console.

Have you guessed how to make the pointer point to the adress of a variable yet? Here is how:

int variable = 2;
int* pointer = &variable;

This is self explanitory if you have been paying attention.

So now let's make a program:

#include
using namespace std;

int main(void)
{
int variable = 2;
int* pointer = &variable;

cout<<*pointer< cout<
return 0;
}


The output will be "2" then the memory address of "variable". Let's go through it:

first, it creates a variable, and a pointer that's assigned to hold the address of that variable. Then, we display what's held at that address. Then we display what's stored in the pointer itself.

There is something new in this; using the pointer for output. Now, once you've assigned the pointer to a variables address, you can use that pointer in 2 ways. Appending the pointer with an asterix (*) is saying I want this to show what is held at the address I'm appointed to. Not appending it with an asterix is saying "just display what is held in this pointer".

To put it easier on the brain, what the pointer actually holds is the memory address of a variable. So, when you do

cout<

you will just be displaying what that pointer holds, like an ordinary variable, which, in the case of pointers, is a memory address. However, if you append it with a * it says "display what is held at the memory address I'm holding". So in the example, it would display 2, because 2 is what's held at the memory address, which in turn is held in the pointer. Is your head hurting yet?

[SIZE=5]WHAT CAN I USE THEM FOR?
[SIZE=2]Yes its all good and well knowing all this, but you may be wondering; "what's the point". This is something that I am still learning, because there are so many advantages to being able to use indirect referencing, to use memory addresses and the likes. As this is already becoming a tedious tutorial, I shall only explain one thing it can be used for, however I might make another tutorial some time explaining other uses of pointers and references.

One use of pointers would be this: If you wanted to make a program to swap 2 numbers around using a function, you would probably do something like this:


#include
using namespace std;

void swap(int a, int b);

int main(void)
{
int a, b;
cout<<"enter a number: ";
cin>>a;
cout<<"\nAnd another: ";
cin>>b;

swap(a, b);

cout<<"a is now: "<
return 0;
}

void swap(int a, int b)
{
int y = a;
a = b;
b = y;
}

Read that code a couple of times over. If you don't understand what I've tried to do, you shouldn't be learning about pointers just yet :P. Can you notice anything wrong? No? I'll tell you. You see, that function cannot make changes to any variables inside another function, as the variables aren't global. You see, if you run that code, the numbers won't change, and your compiler might even give an error. This is because the swap function can't make any changes to a and b in the main function, because those variables can only be changed in the function they were made in (it's all to do with local and global scope you see). This is in the same way that if a variable was made in the swap function (like "y"), main function cannot edit that variable, because it's out of it's scope (you should already know about local and global scope).

The only way this can be accomplished is if you use pointers to edit the variables memory cell. If you make a and b POINTERS in the swap function, they can edit the variable because they have direct access to it, not copies of it. In effect, all arguments passed to the function does, is take a copy of those arguments. So really, it doesn't have the "original" copies of "a" and "b", rather copies of them, so any changes made will be to the copies only, whereas a pointer can edit the original. This would be the code to do this:


[/SIZE][/SIZE][/SIZE][/SIZE][/SIZE][/SIZE][SIZE=3][SIZE=2][SIZE=3][SIZE=2][SIZE=5][SIZE=2]#include
using namespace std;

void swap(int a, int b);

int main(void)
{
int a, b;
cout<<"enter a number: ";
cin>>a;
cout<<"\nAnd another: ";
cin>>b;

swap(&a, &b);

cout<<"a is now: "<
return 0;
}

void swap(int* a, int* b)
{
int y = *a;
*a = *b;
*b = y;
}
[/SIZE][/SIZE][/SIZE][/SIZE][/SIZE]
[/SIZE]


see how this works? The function can now directly edit those variables, without having to deal with copies. This isn't actually that important, but it's just important to know how to use pointers, and that they can be, and are used for a LOT of things in programming.

If you have found any of this hurts your brain, I DON'T CARE! GET OVER IT!
Just as long as you have learnt something in the process.

Thank you for reading my tutorial on the basics of C/C++ pointers, and be ready for other tutorials coming soon...

If you have any questions, or anything I could improve on, please reply and show your appreciation :) (This did take just under 2 hours you know :O)

FLUXINATOR
proslayar

Posts: 147
Joined: Dec 2008
Rep: 10

View Profile
Jan 31, 2009 11:34 PM #349566
O god, i have programming one this semester, and am in line to fail it....
Automaton
2

Posts: 4,779
Joined: Nov 2007
Rep: 10

View Profile
Feb 1, 2009 6:25 PM #350112
If you need a tutorial on anything, I'll be glad to help.