There are several ways to tackle it.
The intuitive approach, which is what most C/C++ programmers think of, is that pointers are memory addresses. litb's example takes this approach. If you have a null pointer (which on most machines corresponds to the address 0), and you add the size of an int, you get the address 4. This implies that pointers are basically just fancy integers.
Unfortunately, there are a few problems with this. To begin with, it may not work.
A null pointer is not guaranteed to actually use the address 0. (Although assigning the constant 0 to a pointer yields the null pointer).
Further, you're not allowed to increment the null pointer, or more generally, a pointer must always point to allocated memory (or one element past), or the special null pointer constant 0.
So a more correct way of thinking of it is that pointers are simply iterators allowing you to iterate over allocated memory.
This is really one of the key ideas behind the STL iterators. They're modelled to behave very much as pointers, and to provide specializations that patch up raw pointers to work as proper iterators.
A more elaborate explanation of this is given here, for example.
But this latter view means that you should really explain STL iterators, and then simply say that pointers are a special case of these. You can increment a pointer to point to the next element in the buffer, just like you can a std::vector<int>::iterator
. It can point one element past the end of an array, just like the end iterator in any other container. You can subtract two pointers that point into the same buffer to get the number of elements between them, just like you can with iterators, and just like with iterators, if the pointers point into separate buffers, you can not meaningfully compare them. (For a practical example of why not, consider what happens in a segmented memory space. What's the distance between two pointers pointing to separate segments?)
Of course in practice, there's a very close correlation between CPU addresses and C/C++ pointers. But they're not exactly the same thing. Pointers have a few limitations that may not be strictly necessary on your CPU.
Of course, most C++ programmers muddle by on the first understanding, even though it's technically incorrect. It's typically close enough to how your code ends up behaving that people think they get it, and move on.
But for someone coming from Java, and just learning about pointers from scratch, the latter explanation may be just as easily understood, and it's going to spring fewer surprises on them later.