Here it is: All About Pointers ======================================================== 1. What IS a pointer, anyway? A pointer is a variable used to store a location. So, what is a location and why do we care? A computer has to have memory. The basic unit of memory is the byte. That memory also has to be organized in some way so that we can access parts of it. It happens that the obvious way to organize it is linearly. That is to say that the memory "starts" at a certain value (say, 1024) and ends at another (say, 640000). What this means is that the computer has bytes of memory that it can read from and write to running from 10000 to 640000. The starting and end points don't matter -- it could be from 0 to 1000000, or from 0 to 10, then 15 to 30, and so on. When we write a program that has something like this: int x = 10, y = 30; int z = x + y; We don't care about memory. Somewhere, 4 bytes are being allocated for each of those integers (4 bytes on a 32bit machine) and numbers are being placed in that allocated memory. No fuss, no muss, no worries about memory. But just because we aren't dealing with it doesn't mean it isn't happening. Memory is being allocated for all three ints. That memory is being referenced whenever we use those variables. Remember: Z is not being assigned to x+y. Z, Y and X only exist in the abstract, they do not actually exist, as themselves, anywhereInstead, what happens is, the compiler lets you author your program in the abstract. What is really happening is different. The contents of the memory location referred to by X is being added to the contents of the memory location referred to by Y and this result is COPIED INTO the memory location referred to by Z. YOU DO NOT NEED TO THINK ABOUT THIS. IT DOESN'T CHANGE THE WAY YOU WORK. It is only meaningful when one is trying to understand pointers. So what is a pointer? A pointer holds a memory location, called an address. A pointer can be used to manipulate the contents of the memory at that address (with the "dereferencing operator," the *). A pointer may be set to point at any address (using the "address operator," the &). The following appears to make things as confusing as possible, but once understood, the distinction between a pointer and, say, an integer becomes clear: ------------------------------------------------------- int y = 4; // y is an integer, referring to a // SPECIFIC and UNIQUE address in memory // that may NOT be changed. The memory // referred to by y contains the value 4 int* x; // x is a POINTER_TO_AN_INTEGER. X // itself refers to a SPECIFIC AND // UNIQUE address in memory that may NOT // be changed. This memory holds the // address to which x "points to" x = 0; // the memory referred to by X contains // the value ZERO (this is called the // "null" pointer, pointing nowhere x = &y; // the memory referred to by X contains // the value of Y's __address__ __in__ // __memory__. x now points to y. *x = 7; // the memory referred to by the value // stored in the memory referred to by X is set to 7 // (that is, the integer_pointed_to_by_x // is set to 7, or y = 7). -------------------------------------------------------- Understanding pointers to other pointers ======================================== Boy, that last one is pretty recursive and hard to follow, Yet if we just remember what we're looking for, it becomes comprehensible (though not easy). When looking at a pointer expression, remember that each dereference operator (*) means "the thing pointed to by." Given that, we should be able to understand the following. What get's printed? #include int main(){ int x, *p, **q, ***r, ****s; x = 7; s = &r; // s points to r r = &q; // r points to q q = &p; // q points to p p = &x; // and p points to x (thank god this is over!) ***r = 32; cout << ****s << endl; } The answer is "32." What the heck does "***r = 32" mean? Let's walk through it. "int ***r" should be read as "r is a (pointer to a) (pointer to a) (pointer to an) int." Thus, we know that r points to the thing pointed to by q which is the thing pointed to by p, which is x. When we write ***r = 32; We are saying: "copy the value 32 into (the thing pointed to by) // which is x (the thing pointed to by) // which is p (the thing pointed to by) r." // which is q That's pretty bad. It's hard to follow, but when we break it into clauses and use the magic words ("the thing pointed to" for * in an expression) we cannot go wrong. The output statement is: cout << ****s << endl; which means: "cout (the thing pointed to by) // which is x (the thing pointed to by) // which is p (the thing pointed to by) // which is q (the thing pointed to by) s." // which is r A little more on pointers: A pointer lets us explicitly refer to ANY memory location. Take the above. Although X refers to a memory location, X referes ONLY to that memory location. You cannot change WHERE X refers, you can only change the value of the memory to which X refers, not X itself. Moreover, NO OTHER VARIABLE EXCEPT A POINTER can refer to the memory location "occupied" by X. X, and only X, may refer to that location. ----- One difference between a pointer variable and any other variable is that a pointer variable may be used with the * operator. ------- Wrapup: You can change the contents of an integer. You can change the contents of a pointer_to_an_integer. int x, *y; x = 7; // x = 7 y = &x; // y = the address of x You can set an integer equal to another integer. You can set a pointer_to_an_integer equal to another. int x = 5, y, *w, *z; z = &x; // z points to x y = x; // y = x = 5 w = z; // w = z = address of x, w points to x ===================================================================== copyright 1997-2003 Robert Rodgers knave@acm.org www.mindtwin.com =====================================================================