Skip to main content

Section 18.2 Pointers

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*.

Note 18.2.1.

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.
To initialize a pointer type, we use the & to get the address of the variable we want ot “point” at. This sample sets p to point at x:
Listing 18.2.1.
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.
p holds the same value as x’s address
Figure 18.2.2. Memory diagram of p storing x’s address.
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.

Insight 18.2.2.

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:
Listing 18.2.3.

Checkpoint 18.2.1.

Declare a pointer to a double named myPointer and initialize it with the memory address of data (assume data is already declared).

Checkpoint 18.2.2.

Double pointer myPointer exists and has been initialized. Make a copy of the value it holds into a new pointer p2.

Checkpoint 18.2.3.

Double pointer myPointer already exists. Make it store the address of data2 (assume data2 has already been declared).
You have attempted of activities on this page.