Pointers in C/C++

Pointers are hated by many first-year students of any dev school, though it really isn't that bad. I am going to try to give you a few elements to help you master those infamous pointers.

I recently gave a lesson on C++ to someone to help him prepare for his exams. His problems? Pointers. And it just threw me back to the days I used to struggle with those too.

Here is why I'm writing this C++ post in the middle of my usual content. I want to help you get through that! And, even if you use and prefer other languages where pointers don't exist, I think it'll be helpful to understand how your computer's memory works.

In this post, you'll learn :

  • What is a pointer
  • How to use it
  • How useful it is

What's a variable?

Let's start by describing what a variable is because I am sure it will help you tremendously to understand. This description is willingly not exactly accurate, so you'll understand better. I also wrote another post that will help you dive deeper into variables, you'll discover some good practices about it or compare how we use it in different languages.

A variable is a memory zone in your computer where you are allowed to stock a value of your choice. It has an address, so we can find it and a name, so you don't have to remember its address. A variable has a type to tell the system how to act with a value.

int variable = 10;

In C/C++, you declare a variable by writing <type> <name> = <value>. The memory address attribution is automatically done by the system. If you create a regular variable, you don't have to worry about the memory address.

You can picture your computer's memory as a giant library where a lot of information are stocked. To find what you search easily, each spot has a unique address.

When you run the code above, you want to stock in the library the variable book which contains the integer 10. The librarist (the operating system) tells us where to put it, say the address is 0x2020.

This way, when we will need what is inside the book variable, we will just have to go to the 0x2020 address to find the integer 10.

What is a pointer?

To understand what a pointer is, we have to repeat something — at least until it gets logical for you — that this is a simple variable.

int* pointer = &variable;

In fact, the only real difference is that the value of a pointer is the memory address of another variable. Then why are * and & added to the declaration of the variable?

printf("%d", variable); // 10
printf("%d", &variable); // 0x2020
Value displayed with and without &

The sign & is used to say that we want to get the address of the variable instead of its value. Remember that you want to stock the address of a variable in a pointer and not copy its value.

The sign * is only used to say we are working with a pointer. The goal is to adapt its behavior when it is a pointer or a value. We will get to that a bit later, though.

If we go back to the library example, having a pointer is having a spot where a book holds as a value the address of another book, in another spot.

To get the value back from a pointer, we have to go to the pointer book's address, let's say 0x3096, in this book the value read is 0x2020. Thanks to that sign * we know it is in fact a pointer and its value is the address from another variable. So we go to the address 0x2020 to discover the value written in the book is the integer 10.

The library example can look a bit simple, but it helps to visualize the memory of the computer and understanding how it works. You can replace the library by what you want: a big board with numbered cases, big furniture with numbered drawers. The goal is to make this abstract notion (computer memory) something real, concrete that you already know (furniture, board, library).

What are pointers for?

Now we know what pointers are and how they work, but there is still a question: what are pointers used for? Why would we need pointers?

Pointers are useful for several things. First, as they refer to other variables in memory, they allow us to have access to one variable at different spots of the program.

void reaction(int* arg) {
    *arg = 1;
}

int action() {
    int number = 0;

    reaction(&number);

    if (number == 0) {
        return 1;
    }

    return 0
}
Pointers allow us to access in reaction() a variable created in action()

Of course, it is a read/write access. The pointer is not a copy of the variable but a reference to it.

Pointers also have us reduce the execution time and the space used in memory by a program. Because the variables are not duplicated in each execution context, we use less memory space.

They are also pointers to functions, but that will be for another post. Anyway, if you understood what I just said, I think you have the knowledge to understand everything else on pointers on your own.