I'm talking about ANSI C/C++ here; I know this also applies to Borland ObjectPascal (albeit with different syntax). Your mileage may vary with other languages, I suppose. (K&R C is somewhat more blasé and open-minded about certain things, but if you're writing code in K&R C you'd better grasp this stuff at least as well as I do, in which case everything in this writeup will already be known to you).

A pointer is really just an integer; by convention, the value it holds is either zero, or an address in memory to which your program has access. If you assign the pointer to something, you're making a copy of an address; if you assign something to the pointer, you're changing the address that the pointer holds. None of this will have the slightest effect on whatever resides at the address(es) in question. Imagine having an address book with Madeline Albright's phone number in it. If you change that number, or if you write it down somewhere else, Madeline Albright is not affected at all. The only way Madeline Albright is going to take notice of what you're doing is if you dial the number: Dereferencing is "dialing the number". It looks like this:

    char c = 'w';
    char *p = &c;  //  "char *" is a pointer to type char; 
                   //  "&" gives us the address where c lives.

    //  First, let's look at the value of p, which is now the 
    //  address in memory where c lives:
    printf( "address:           %d\n", p );

    //  Now here it is: * is the "dereferencing" operator. 
    //  It will give us the thing that p points at, rather than
    //  the value of p itself; the "number" is "dialled":
    printf( "value at address:  %c\n", *p );  


That code snippet produces the following output:

address:           6553072
value at address:  w