C Pointers

C Pointers

What are pointers and why do we use them

·

6 min read

Hello! Today I will explain to you what are pointers in the C/C++ language and what are they used for. This is my first C post on this blog and if you want to see more or want to feedback on this, please comment.

What are Pointers?

To understand what are pointers, let's first draw a table representing our memory. Our memory can be represented as a table composed of two columns: one for the address of that position and one for the value set at that address:

Let's now store 4 at the address 0x1000, like if we did:

int a = 4;

Our new memory should look something like this:

Ok, imagine we want to remember where our 4 was allocated, its address. To do this we simply store the address in a new position, so we store 0x1000 (which is the address of 4) into 0x1004 and we end up something like this:

What we created is a pointer.

A pointer is simply a variable that holds a memory address

How do we write a Pointer in C?

Create a Pointer

To create a pointer we first need to create a variable that we want to take the address from:

#include<stdio.h>

int main() {
    int myVariable = 5;

    return 0;
}

After that we want to create the pointer, the syntax for it is:

// [type of the variable we take the address from]['*'] [name] [assignment]

Here's how we would create the pointer for myVariable:

#include <stdio.h>

int main() {
    int myVariable = 5;
    int* pMyVariable  = &myVariable;
    // int *pMyVariable  = &myVariable; is the same thing

    return 0;
}

Let's analyse this code:

  1. We create the variable myVariable set to 5;

  2. We create a pointer to store the address of myVariable with this method:

    1. We give a type to the pointer, the type must be the same as the variable we're taking the address from, in this case int;

    2. After the type or before the name we add *, this indicates that the variable we are creating is a pointer;

    3. We give a name to the pointer, usually, it's 'p' followed by the name of the variable with a first capital letter;

    4. We assign the address of the variable, to get the address we just need to precede the name of the variable with the & symbol;

If we print the value and the pointer we should get something like this (obviously the memory address will be different):

#include <stdio.h>

int main() {
    int myVariable = 5;
    int* pMyVariable  = &myVariable;

    printf("myVariable value: %d \n", myVariable);
    printf("myVariable address: %p \n", pMyVariable);

    return 0;
}
>> "myVariable value: 5" 
>> "myVariable address: 0x7ffc13175764"

Get the value from a Pointer

Now let's imagine a memory where is stored a certain value at a certain address but we only know the address of this value but not its content. We can access its value by simply creating a pointer to that address and print what's inside. We do that like this:

#include <stdio.h>

int main() {
    int unknownValue = 2023; // assume you don't know it

    // create a pointer to the value
    int* pUnknown = &unknownValue;
    printf("The address of the unknown value is: %p \n", pUnknown);

    // we print the value from that address 
    printf("The value stored in that address is: %d \n", *pUnknown);

    return 0;
}
>> "The address of the unknown value is: 0x7ffc503edd64" 
>> "The value stored in that address is: 2023"

Let's analyse this code:

  1. Assume we have a variable called unknownValue of which we don't know the content;

  2. We create a pointer to that variable like before called pUnknown;

  3. To get the value at the address indicated by a pointer we use something called dereference, so to print the content we write our printf and assign our positioner the name of the pointer preceded by *;

Now that we understand the basics of pointers in C/C++, let's explore how they can be used to access and manipulate data in memory.

Accessing and Manipulating Data Through Pointers

Pointer Arithmetic

One of the powerful features of pointers is their ability to perform arithmetic operations. When you perform arithmetic operations on pointers, they move by a certain number of bytes depending on the data type they are pointing to. For instance, if you have an int pointer and you increment it by 1, it will point to the next integer in memory, which is 4 bytes (on most systems). Similarly, decrementing the pointer will make it point to the previous integer.

Here's an example:

#include <stdio.h>

int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int* p = numbers; // points to the first number in the vector

    printf("First element: %d\n", *p);

    p++;
    printf("Second element: %d\n", *p);

    return 0;
}
>> "First element: 10"
>> "Second element: 20"

Passing Pointers to Functions

Pointers are often used to efficiently pass data to functions, especially when you want to modify the original data inside the function. By passing a pointer to the data, you're essentially giving the function direct access to the memory location of that data.

#include <stdio.h>

void modifyValue(int* pointer) {
    *pointer = *pointer * 2;
}

int main() {
    int num = 5;
    printf("Original value: %d\n", num);

    modifyValue(&num); // we pass the address
    printf("Modified value: %d\n", num);

    return 0;
}
>> "Original value: 5"
>> "Modified value: 10"

Pointers and Arrays

We've seen in a previous code snippet that the name of an array is associated with its first element's value:

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int* ptr = arr;

    for (int i = 0; i < 5; i++) {
        printf("Element %d: %d\n", i, *(ptr + i));
    }

    return 0;
}

Null Pointers

Sometimes you want to indicate that a pointer does not point to any valid memory location. You can use a special value called a null pointer for this purpose:

#include <stdio.h>

int main() {
    int* ptr = NULL;

    if (ptr == NULL) {
        printf("ptr is a null pointer\n");
    } else {
        printf("ptr is not a null pointer\n");
    }

    return 0;
}

Why Pointers Matter

Let's dive into why pointers are a big deal in the world of C/C++ programming.

Think of them as a special map that helps us find and change information stored in our computer's memory. When our programs handle lots of data, like lists of numbers or words, pointers help us do it efficiently. They're like shortcuts that allow us to easily move around and update data without wasting time or memory. Pointers are also essential when we want to create cool things like dynamic lists or smart ways to store info. So, when you're on the journey of coding with C/C++, learning about pointers is like getting a superpower; it lets you control and organize your programs better. It helps you build programs faster and smarter!


So, this was a brief introduction to C pointers. If you want to learn more about pointers I suggest you look up: Pointer Type and Size (difference between 32/64 bit and other types), double pointers (for dynamic memory allocation), and memory allocation.

On this blog I don't only cover C and C++ topics but also TypeScript, React, Flutter Development and others so if you are interested in one of these, spend 5 minutes checking out my blog :). Hope to see you reading the next post!