Pointers – What are they and why they are our friends!

Pointers are one of the most important and fundamental parts of the C programming language. According to the language creators themselves, “A pointer is a variable that contains the address of a variable. Pointers are much used in C, partly because they are sometimes the only way to express a computation, and partly because they usually lead to more compact and efficient code than can be obtained in other ways.” (KERNIGHAN and RITCHE, 1988, P. 93)

Before we go into pointers and what they are, we need to understand how the C language works with memory.
When we create a variable, the C compiler will allocate that memory inside a random memory address with the size of the variable (let’s say, 4 bytes for an int variable) and puts whatever we put inside the variable onto that memory address. If you execute the example code below, you will get a random value from the pointer.

#include<stdio.h>
#include<stdlib.h>

int main(){
    int var = 2;

    printf("Var content: %d\n", var);
    printf("Var address: %p\n", &var);

    return 0;
}

The %p format specifier means we want to display a pointer value and the & symbol represents the address memory for that variable.
As you can see, it prints the “2” we assigned for that variable and right below, the address for that variable. It will not be the same every time, as the RAM memory is volatile and will be erased every time you restart or turn off your computer.

You can declare a variable as a pointer by simply adding a * next to the name of the variable.

But before we dive deeper into this, we need to learn a little bit about pointer arithmetic!

Pointer Arithmetic is a way to deal with pointer addresses by using arithmetic with them. Let’s see in the example below.

#include<stdio.h>
#include<stdlib.h>

int main(){
    int number = 2;
    int *var = &number;

    printf("Pointer address before add: %p\n", var);
    var++;
    printf("Pointer address after add: %p\n", var);

    return 0;
}

When we execute this code, it moves the var pointer variable 4 bytes, because that’s the size of an Integer. With this, you are directly accessing the computer memory, but it’s not a good idea to do that because you never know what’s inside a memory address.

We can also select an index on a matrix or array by doing the following:

#include<stdio.h>
#include<stdlib.h>

int main(){
    int intArray[3] = {3, 6, 1};

    printf("%p\n", intArray+2); //This will print the 3rd element of the array
    printf("%d\n", *(intArray+2)); // This will also print the 3rd element of the array

    return 0;
}

Alright, done with the theory. Now, let’s say you’ve been hired to work at a game company and you’re making a platformer game. You’ve been asked to write a function in C that will decrease the player’s lives if he falls into a bottomless pit. So, you write the following code:

#include<stdio.h>
#include<stdlib.h>

void decreaseLives(int playerLives){
    playerLives--;
}

int main(){
    int playerLives = 3;

    printf("Lives before decrease: %d\n", playerLives);
    decreaseLives(playerLives);
    printf("Lives after decrease: %d\n", playerLives);

    return 0;
}

Oh, something happened. We weren’t able to decrease the lives. But why?
Well, that’s simple! We’ve just passed the value of the variable, not the variable itself. The playerLives variable inside the main has a different memory address than the playerLives variable inside the decreaseLives function. We can see that by printing the pointer of that variable, as seen below.

#include<stdio.h>
#include<stdlib.h>

void decreaseLives(int playerLives){
    printf("Address #2: %p\n", &playerLives);
    playerLives--;
}

int main(){
    int playerLives = 3;

    printf("Lives before decrease: %d\n", playerLives);
    printf("Address #1: %p\n", &playerLives);
    decreaseLives(playerLives);
    printf("Lives after decrease: %d\n", playerLives);

    return 0;
}

They are different addresses and, therefore, different variables! OK, but how can we pass the same variable? Using pointers, of course! Let’s see the example below.

#include<stdio.h>
#include<stdlib.h>

void decreaseLives(int* playerLivesFunc){
    printf("Address #2: %p\n", playerLivesFunc);
    (*playerLivesFunc)--;
}

int main(){
    int playerLives = 3;

    printf("Lives before decrease: %d\n", playerLives);
    printf("Address #1: %p\n", &playerLives);
    decreaseLives(&playerLives);
    printf("Lives after decrease: %d\n", playerLives);

    return 0;
}

Alright, it worked! But, it is a little bit confusing, right? That’s why I’ve made this super professional drawing in GIMP to illustrate what the pointers are.

Cool, but why should we use pointers? Shouldn’t we use global variables instead? Well, you COULD use global variables, but only if your functions are in the same file as your main, if you create a header file for your project, your global variables will not be capable of doing their work, and that’s why pointers are your friends!

I hope you enjoyed and/or learned something new! Until the next time.

21yo                              If there's C, I like it. And that includes C++ and C#.         Homebrew development, reverse engineering and low-level coding are my favourite topics.

Leave a Reply

Your email address will not be published. Required fields are marked *