All data and code are stored in memory. The location in memory where they are stored is known as the address of that data or code. Usually they are accessed through variable names that represent them, such as counter, printf, etc. We can, however, also access data using its address, rather than a formal name. This is done using pointers, special variables which store the address of data. Following are several annotated examples of simple pointers at work.
int* x; // Declare x, a pointer to an integer.
int y; // Declare y, an integer.
float* r; // Declare r, a pointer to a float.
float s; // Declare s, a float.
x = &y; // x gets y's address -- it points to y.
r = &s; // r gets s's address -- it points to s.
The next few are a tad trickier. We use the "*" to dereference the pointer. Basically, this means to access whatever it is the pointer is pointing to. You can think of it as counteracting the "*" used in the declaration of the pointer; they neutralize each other, making the result a regular variable.
*x = 15; // Set value pointed to by x -- y -- to 15.
cout << *r; // Print value pointed to by r: s.
The first is the idea of pointers being equivalent to lists. This is a crucial idea in C and C++. Essentially, instead of thinking of a pointer as pointing to a single variable, you can think of it as pointing to the first variable in a list of variables. Likewise, a list can be accessed without any subscripts to find the pointer to the first element in the list. It works like this:
x = new int; // Allocate array of 8 integers.
*y = 8; // Set first element of y-list to 8.
x = 7; // Set fourth element of x-list to 7.
Note how pointer notation can be used for the list y, and how list notation can be used for the pointer x.
This brings up a similar topic: pointer arithmetic. Since a pointer is a memory address, you might think that adding "1" to a pointer would simply make it point to the next byte of memory. The C compiler, however, is smarter than that; it realizes that you're adding something to a pointer, you probably want to make it point to the next element of whatever you're pointing at. So instead of adding whatever you specified to the pointer, it adds that times the size of the object the pointer points to.
int* x = new int;
x++; // Add four to x pointer, to
// point at next integer.
x = 5; // This was originally the second
// element in the array.
x--; // Subtract 4 again from pointer.
*(x + 2) = 6; // Set third element (second after the
// first) to 6.
cout << x; // Will now print "5".
cout << x; // Prints "6".