Definitions

A pointer is a variable which contains the address of another memory location. Pointers are used to access a memory location indirectly — that is, without having to have that memory location declared right here in our own local scope. (AKA our visible or accessible scope.)

Declarations

When declaring a pointer, you must tell the compiler the type of data to which you intend to point. To distinguish a pointer type from a normal type (as for a variable or constant declaration), our C ancestors used the star (*) symbol as a modifier for the [base] type. So, to declare a pointer (we'll cleverly call it ptr) to a short integer, for instance, we would declare 'short * ptr' in our code.

But isn't the Asterisk..?

The spacing around the * symbol here is optional, as usual. This leads to many different styles of spacing and warring camps of programmers...again, as usual. The problem with the spacing is that some programmers are lead to believe that the * symbol is completely independent of the type and the identifier. However, given its role as a type modifier, it seems more logical (and, indeed is true) that it is actually associated with the data type ...which, in turn, defines the very nature of the identifier.

The other point (sorry...couldn't avoid it...*snicker*) at work here is the fact that the * symbol used to 'modify the data type', doesn't truly stick to the type it modifies. Instead, it correlates to the identifier! This leads to programmers creating declarations such as 'type* p, q;' and thinking that both p and q are going to be pointers — since the * was modifying the type. Instead, they've declared p as a pointer to the correct type and q as a plain old variable of that type! To make both identifiers be pointers, you would have to declare them like this 'type *p, *q;'.

So, the nature of the thing makes it seem that the * should reside with the type, but the syntax of the thing requires that the * reside with the identifier! Most perplexing! Our champion of choice here is the trusty typedefinition:

    typedef type * TypePtr;
    TypePtr p, q;

Now both p and q are correctly declared as pointers to the desired type! The typedefinition makes the * stick to the data type it is modifying as nature intended — language syntax rules be damned! All hail the typedefinition! typedefinition! typedefinition!

Terminology

When dealing with a pointer, you must also be careful of your vocabulary (aka terminology)! Many a fine algorithm has been delayed or outright doomed by one programmer loosely discussing the 'value of the pointer' and another mis-interpreting the meaning.

With a pointer, the value is technically the address of some other memory location. Note its basic definition: a pointer is a variable which holds the address of another memory location. Therefore, when we discuss matters involving pointers, we should always define terms amongst ourselves before-hand. A reasonable convention is to use one of the terms 'target' or 'destination' for the memory location to which the pointer points and then leave the terminology about the pointer itself alone. Then a discussion of the 'value of the pointer' is understood by all involved to mean the pointer's contained address. And the phrases 'value of the target' or 'target's value' would as simply be clear in meaning.

Of course, we could always then take the address of a pointer — and store that in another pointer...perhaps that's a topic best left for another day, 'eh?

To Point, but to Where?

What value should we place in a pointer variable to indicate that it does not yet point to a valid address? We long ago created the symbolic constant NULL to represent this idea.

In C, the NULL identifier is, oddly enough, a C-style constant (aka a #define macro with no parameters) which is [typically] equal to the value 0. It is currently a matter of fervid debate in the C++ world as to which is the more proper to use — the named constant or the literal.

Well, technically, the debate is truly over whether the literal or a C++-style constant would be better. But the way the standard, all recent technical reports from the standards committee, and the stern opinions of Bjarn himself are worded, there is no real way to define such a beast...IMHO.)

UPDATE: It appears we were all wrong. Recent standards efforts have produced such a constant. It is named nullptr — note there is no underscore! Should your compiler support this (such as g++ since 4.6 or so), it would be preferred to nullptr.