Now that we know how to access the memory address of a variable, we need a way to store that address. We can do this using a pointer. A pointer is simply a variable that stores the memory address of another variable. We declare a pointer by using an asterisk * between the data type and name of a variable. For example, if we want to create a pointer to an integer, we would write int* p;. (This use of * is just like how we use & to indicate a reference.)
Remember that it can help to read declarations backwards. A good way to pronounce int* p; is โp is a pointer to an integerโ or โp holds the address of an integerโ. We would pronounce Circle* c1; as โc1 is a pointer to a Circleโ. Note that the * is part of the data type. p does not have the type integer, it has the type int*.
The * can have spaces on either side of it. Some programmers prefer to write int *p; to make it clear that p is a pointer. In this book, we will always place the * next to the data type to focus on the idea โthe type of p is pointer to an integerโ rather than thinking โthe type of *p is integerโ.
The main downside of this approach is that you canโt use int* a, b; to declare multiple pointer type variables at once. You either need to declare one variable per statement or use int *a, *b;. As we have seen before, the more things you try to cram into one statement, the more deeply you need to understand picky details of the syntax.
Note that printing out p produces the same value as printing &x. This should not be surprising, as we initialized p to &x. A memory diagram of this example is shown below.
Now try running the program using Codelens. It shows p as an arrow pointing to x. This is a common way to represent pointers in memory diagrams and a useful way to think about them abstractly. (That is why they are called โpointersโ - they point to things!) This kind of arrow should look familiar from working with references. It is not a coincidence - both references and pointers are ways to link to other memory.
Although we like to draw abstract diagrams and think of pointers as magical arrows that point to other memory, it is important to remember that a pointer is really just a memory address. Any code that works with a pointer is just working with that address.
It is possible to reassign pointers and to copy pointers. Try running this sample both in the ActiveCode and in Codelens. It changes the address that p is storing to make it โpointโ to y instead of x. It then copies that address to another int* named q, which means that q is also โpointingโ at y: