Many of you are fine programmers in all respects - but fail to understand pointers. They are simple! Honest!
Pointers On (Using) Pointers
Ok - I am going to try and make pointers accessible to those of you who are already familiar with scripting languages. I'll give a couple of different ways to try and wrap your head around them - and try to avoid noddy examples that make you think "Why would I ever do that?"
First of all:
What IS a Pointer?
There is a bit of confusion and terminology to wade through first. The word 'pointer' is used to mean either a variable which HOLDS a pointer - or the VALUE of a variable that holds a pointer. This is evil and sloppy. Sorry.
Languages
I am talking here, mainly, about C-style pointers. Many lower level languages do not have explicit pointers at all, and many higher level languages have no need of them. But understanding what the higher level language is acttually doing can be useful.
So - here are some different ways to think about pointers.
Webs
A pointer is, in its simplest form, a reference to something. You could call a URL a pointer. It is WAY nicer to be able to pass around "http://www.morat.net/" than it is to pass around the contents of that web-page.
So - this is the first metaphor I'm gonna use. A URL can be stored in a variable for later use, sent to people - and you can look at whatever it points to. Or you could change it - perhaps adding a "/members" on the end - and THEN look at it. Or you could change whatever it is pointing at.
There we go, simple metaphor the first.
Arrays
Now, most computer programs don't have webservers and URLs inside them. Usually you use something simpler. An array (you ought to understand by now) is a whole bunch of seperate variables - all lumped together under a single name, and indexed by some method. That index, guess what, is a pointer! Whether the array is indexed [0,1,2...] or whatever - that array index is basically a pointer into the array.
Memory
Ok, this is low level stuff. You remember how Usbourne described a computer? Lots of little pigeonholes with slips of paper (with numbers on) in them? The hole was a memory address - and the paper was the data. You could PEEK at the paper, or POKE a new bit of paper into the hole?
Ok - hold that image. Now, those little robots that run around inside your computer obviously need a way to find which pigeon hole they want. That's what the address bus was for - it knew where each memory address actually was, and could drive the little computer people to the right one.
But, this being a computer - the memory addresses weren't like street addresses - they themselves were just big numbers. Maybe 327680 marked a memory location that held the current colour of the screen borders. But you don't need to know that.
The CLEVER thing is that those addresses are just the right size to be written down on a scrap of paper, and put into a memory address of their very own. This let's you look in one hole, then read what it says, and go there and look in - and so on. Like a big treasure hunt game. But this is the basis of all computer 'thought'
Ok - enough Usbourne (neat little books though) - a pointer is itself just an integer. It just so happens that you can use it to look at (and modify) arbitary bits of memory. This is just as dangerous as it sounds - but it is also useful.
Why Pointers are Good
I hope you have a vague idea in your head as to what a pointer is now. I shall now attempt to show you why they are a good thing to use. Specifically, I'll highlight some (hopefully real-world) examples as to where you would prefer them over another languages solution. To be fair, I'll then go and point out the bad things too...
Better than passing huge stuff around
Pretty much the URL example I gave. Let's say, for sake of example, you just scanned an A4 image in at 19,200dpi without thinking, and the final file came to 2.6gig. Now - imagine that your image editor had to actually copy it around to pass it into the jpeg compression algorithm. No chance. So instead, you just pass a pointer (or a reference or a handle or whatever) and everything is good.
Obviously, 2.6gig is pretty extreme - but if you are writing an application for speed you want to be passing around even quite small bits of data as rarely as possible. A couple of bytes is fine - but ten bytes or so and it starts to really hurt your bandwidth. So, especially if you want to do things quickly, or the things you want your program to edit could be quite large, then you want to use some form of pointers.
Better than arrays - referencing a new array
As I said -an array index is basically a pointer. You could happily code a routine to be passed in an array index, and then look up whatever it needed there. In fact a lot of programs work this way. Nothing wrong with it. BUT - you have implicitly passed the name of the array to use.
So what happens when you change the name of that array? (because your company comes down on you like a few thousands of newtons of weight or bricks about "no global variables" perhaps) Yup, you gotta go through and change all the times you use it. #defines help - but what happens when you want to have two pretty similar arrays that are used for pretty much the same thing? You've got to add another argument to the function to tell it which to use and go back and change all the uses of that function...
Anyway. A pointer is always an index into ALL of the memory available to your process - so you can happily pass a pointer to a part of any array you feel like.
Dynamic allocation
This is probably the main and best reason to use pointers. If you don't know how many copies of something you need then you really need pointers (or something like them)
Rather than, at compile time, guessing and saying "Oh, make the array 500 long" and ending up both having to cope with using up too much memory whiole idle and not having enough memory for demanding users - instead you can grab more memory on the fly, point accesses into it, then free it when you don't need it any more.
Better still, you get a lot of "No memory available" checks done for you.
Of course, this isn't entirely simple - memory leaks are probably the most-made-mistake in programs right now, but it's certainly usually better than the alternative.
Better than memory - typing
Well - there's nothing to stop you using the entirety of memory as your own personal scratchpad. But I advise against it.
Pointers give you the confidence that when you think you are pointing to a string, or a network handle, or a kitten - you atually are.
I shouldn't have to preach about type safety. Even if you are being type lax, pointers remind you when you need to do conversions.
Multiple returns
This is a flaw in the basic C language. Functions can only return one value. So to return more than one thing from a function, you pass in a pointer to a scratch bit of memory, and the function then uses that to put data in the scratch. Not ideal, but it does work.
Dynamic linking
I don't actually want to know which graphics driver I am talking to - I just want to know its interface and where it is. This touches on passing around big blocks of memory (you want your network driver to COPY every byte it gets sent?)
Basically - if you want to link together APIs - especially APIs from different languages - you need pointers.
Direct Hardware Access
Not really an issue on a PC normally - you'll have an OS to do this stuff for you. But if you're writing device drivers, or coding for an embedded platform - you will NEED to passpointers around.
When you should NOT use Pointers
Threading
It's bad enough making variables thread-safe, making arbitary areas of memory that multiple things might be pointing at safe is a nightmare. Sometimes you have to buckle down and do it - most times you are gonna want to use a standard library that copes for you.
Typing
Let's say I am passing around some very high level object with state. A kitten. It's got all sorts of ways in which you can access it, you can stroke it, you can feed it. Now I pass you a pointer to it, and you decide to randomly cast it to a puppy, dock its tail, cast it to a full grown cat and THEN pass it back. I end up with a kitten with no lungs.
If you need to know that other people aren't changing the internals of your objects (with unintended consequences from not obeying consitency rules) or you need to know that they aren't looking at the internal secrets - then don't pass pointers.
High level languages that do it for you
Many languages have a 'vector' concept, which is like an array - but it handles getting bigger when needed automatically. If your language also handles 'map' for iterating a function across a vector then you really have very little demand for pointers. Really, performance becomes your only issue then.
Noddy examples
There are so many noddy examples of what pointers are for used in teaching books. "Add four to everything in this array" for example. Yeesh. If you're doing something noddy - avoid pointers.
Function Pointers
A function pointer is a pointer to a function. You can then pass around, effectively, the name of a function, and call it later. You can but never should modify that function, or iterate on to the next function in the code.
These things are so misunderstood it's untrue. They are also usually used with noddy examples. So instead I'll give you the ONE good reason to use them.
Call-back's.
Very very often you will want to tell another module "Do something, then tell me when you are done" If it's a blocking call, this is simple - you just wait for the call to return, and go on knowing it's been done.
But just as often, you want to say "Go do this while I go do something else, THEN notify me" You don't want to have to create a whole new thread just to block on a seperate return. So, instead, you pass a pointer to a function for it to call when it has done. Simple.
Rather than having an API that says "Oh yeah, I'll call RequestReady() on you when you are done" you can have it call whatever you like. Which is sorta useful when you're using more than one API.
Syntax
In C (and hence in C++) pointers are defined as follows:
Whatever* name;
Name is now a variable which holds a pointer to things of 'Whatever' type. eg. Int* int_ptr;
To get a pointer to a specific thing you use & For example:
Int four = 4;
int_ptr = &four;
To change the pointer around you use normal math. To edit (or view) whetever the pointer points at, you use *
Obligatory noddy example.
printf ( "%d", *int_ptr );
four ++;
printf ( "%d", *int_ptr );
Should print out 4 then 5.
Advanced Study
Is beyond the scope of this column. But you will find many tools and aids on using pointers. A lot of work has gone in to finding ways to make pointers less dangerous.
But you should at least be in a position to look at them, and think "Oh right, that is what they are for"