DEV Community

loading...
Cover image for Make sense of pointers

Make sense of pointers

#c
jmau111 profile image Julien Maury Originally published at blog.julien-maury.dev Updated on ・3 min read

Let's have a look at "low-level stuff".

You know what they say, you want something in C, do it yourself!

Disclaimer

There won't be any diagrams. I want to insist on what pointers are and why they are useful, and how I understand them. It's not about code and every possible way to use pointers in C.

Lets start with arrays

Arrays are handy. We use them to store multiple values:

#include <stdio.h>

int main () {
    int arr[] = {13,27,51};
    printf("%d\n", arr[2]);
    printf("%d\n", *(arr + 2));
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Run this code, and you'll see that arr[2] is the same as *(arr + 2). All languages built on top of C, a.k.a the C-family programming languages, follow that fundamental principle.

While you won't see pointers in those high-level languages, they are all over the place in C.

N.B.: *(arr + 2) stores the address of the first element in the third row

Make sense of memory

What is the computer's memory? It's essentially a certain amount of bytes, and each byte gets a reserved address. The program will store contents (a.k.a values) in those addresses.

RAM stands for random access memory. Every time you change or execute something on your computer, you are using RAM, but it gets lost if you switch off your machine. That's why you need to save your work in files, which live on the disk drive (hard disk).

Make sense of pointers in memory

When you add variables, you ask for a certain amount of space (bytes) in memory (RAM). We just saw each byte gets a reserved address in memory.

You can see bytes as cells, so the memory is nothing more than a colossal array composed of cells. Every cell has its location (~ its address). If you point to that address, you get that cell and what it holds.

Because computers only understand 0 and 1, those cells hold binary representations of strings, integers, or any valid data types you might use.

N.B.: It's not 100% accurate, but that should give you some hints.

Pointers as addresses

When you write:

#include <stdio.h>

int main () {
    int number;
    number = 111;
    int* pointer = &number;
    printf("%p\n", pointer);
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

You ask for some bytes in memory. You call that group of bytes "number", and you put "111" in it. Then you create a pointer with an integer type that holds this group address in memory.

If you execute that program, you will get something like 0x7ffeedfe58a8, but what the heck can you do with this address?

What's the point of pointers?

Pointers are powerful. We don't need to copy variables over and over to use them. We know exactly where they are in memory, so we can easily manipulate them, and changes take effects everywhere it should.

Do not repeat yourself (DRY)!

Imagine that you store a lot of data in a variable, e.g., a big array. Instead of copying it every time you need it and kill memory, you would have a better approach and point to where it already lies in memory.

Function pointers in C

In C, function pointers allow for a callback mechanism. In other words, you can call your functions for a specific event. It's useful because, in C, you don't have any run-time representation.

It's also useful to reduce code clutter (eliminate the too many if/else and switch statements).

The syntax is quite weird, though. You use something like:

<return_type> (*<pointer>) (args);
Enter fullscreen mode Exit fullscreen mode

Conclusion

I'm not going to lie. You might not fully understand pointers until you use them for real, but, hopefully, this introduction gave you some hints.

This concept is quite central in computer science, and not easy to master, especially in C.

Discussion (11)

pic
Editor guide
Collapse
vlasales profile image
Vlastimil Pospichal

Typography:

int* pointer = &number;

or

int *pointer = &number;

?

Collapse
jmau111 profile image
Julien Maury Author • Edited

there is no typo in the article, I always use the most portable and less confusing syntax ;)
so, to me, the first one

Collapse
pentacular profile image
pentacular

So, what does this declare? :)

int* a, b;
Thread Thread
jmau111 profile image
Julien Maury Author

Is it a real question or did you find something false in the article? I'm not sure so I prefer asking you before actually answering to that.

Thread Thread
pentacular profile image
pentacular

Your claim is that "int* a;" is more portable and less confusing.

So I'm asking what "int* a, b;" does to see if you've really thought it through.

What is the type of b given this declaration?

Thread Thread
jmau111 profile image
Julien Maury Author

int *a = &b; is like int *a: and then a = &b;, IMHO int* a = &b; is less confusing.

Thread Thread
pentacular profile image
pentacular • Edited

So, given "int* a, b;" what is the type of b?

Thread Thread
jmau111 profile image
Julien Maury Author

I'm trying to use explicit things and you give me examples of "implicit" declarations, which is kinda confusing and pretty much my point. b would not have the type you might expect, you get int here. I dit not use that in the article.

I prefer splitting declarations than inlining with commas. Not saying it's the best practice, but it's less confusing, at least for me.

Thread Thread
pentacular profile image
pentacular

What's implicit about those declarations?

My point is that because "int* a, b;" has that kind of confusing behavior, it's odd to claim that you chose it because it is the least confusing syntax.

There are many good arguments for it, but least confusing doesn't seem to be one of them. :)

Thread Thread
jmau111 profile image
Julien Maury Author

it's not what I've said. I'm not inlining declarations like you. I respect your opinion, but I disagree with you here. Anyway, thanks for pointing that :) I will see if, in practice, it's handier or not, smarter or not.

Thread Thread
pentacular profile image
pentacular

By all means. :)