If you’re a Sturgill Simpson fan, you’ll get the reference. If not, you gotta’ fix that.
I just wrapped up Part 3 of Dr. Chuck’s C Programming For Everybody, and while I had a basic grasp of pointers from working with linked lists, this section really helped solidify my understanding of what’s happening under the hood. Coming from high-level languages, I had several “aha” moments, and I’ve distilled the most valuable takeaways. No fluff, just the essentials for anyone making the jump to low-level programming. If you’re interested in such things, here we go:
Why I Think Pointers Could Seem Hard to Understand
From what I’ve heard and read, many people struggle with pointers. I don’t think this is because pointers are confusing in and of themselves, but because pointers in everyday life aren’t recognized as they should be. I feel this is because of the fact that we allow other things (besides non-computerlike pointers) in our physical world to represent two things having a connection.
For example, we humans write “1 2 3” and instantly think “oh, that’s a list of numbers.” But under the hood, whether in computer memory or human thought, there’s some connection medium that is required to go from one thing (in this case a number) to the next. That “connection medium” is a pointer.
Put another way, let’s say you have four dots: orange, blue, red, and green. They’re stuck to a wall – you can picture them in the room that you’re in right now. Someone walks in and says, “that’s a list.” But nothing is connecting them, so to you, it’s not. With the list of numbers, it’s pretty commonly understood that those three numbers are connected to each other sequentially. With the four dots, there’s no real “agreed upon” connector. Memory addresses are the same way, which is why you need pointers. You need something to say, “after this, go here. Then after that, go there. And then after that, go there.” That, in essence, is any data structure you can imagine.
At the end of the day, I don’t think this is an oversimplification. This is actually just how computers work.
Building a complex data structure is a completely different ballgame, but the core pointer idea stays the same. More on pointers and memory in a bit.
Freedom, Baby
C gives you the most freedom, but it also comes with the strongest probability of shooting yourself in the foot. Some of the deadliest bugs in history have come from the C programming language, mostly due to the deadly trap known as “buffer overflow”.
CPU Architecture Demystified
While working with memory, I learned, or rather cemented the fact that when we see “x86” or “x64” architecture for a computer, that literally just refers to the size of the individual memory addresses.
“x86” = 32-bit addresses
“x64” = 64-bit addresses
In hindsight, this may seem obvious (and maybe a little boring) to some, but it’s cool to officially cement this distinction in your brain after working directly with the CPU and memory.
More on Memory
You can think of memory as a giant array of addresses. It helped for me to visualize memory as a street of homes as far as you can see, except for the fact that there aren’t any houses facing each other, it’s just houses back to back to back to back, for as far as you can see (not infinity, unless you’re Google Cloud or Azure or something). I stole that “street” analogy from Reddit, which is where the light bulb clicked for me. I think once the actual structure of computer memory is realized, understanding a computer and programming becomes so much more fun (and interesting).
Understanding Pointers = Baller Status
Pointers aren’t just a theoretical flex. I recall people, even mentors of mine, talking about pointers like they were some elite-level concept. That’s one of the reasons I took this C course. Pointers were supposed to be the final infinity stone in my chamber. I was planning on taking over the world after learning C and the pointers that came with them. I would become the supreme ruler of the world! Truth is, I’m a little disappointed. I thought they would be harder to learn, even including the use of them when it comes to connecting structs together for things like linked lists and hashmaps (dictionaries if you’re coming from C#). To my surprise, it all kind of quickly came together (relative to the majority of headaches I’ve faced while learning to program), which is weird because pointers are actually very powerful and I feel like knowledge of them unlocks so many possibilities for what you can do with a computer. At the end of the day, pointers are just memory address of variables that are used to mainly to tie things like lists, dictionaries, and other data structures that represent our world, together.
In addition to pointers being the foundation of all data structures, another reason understanding pointers is beneficial is because programs/functions/methods/routines (whatever you want to call them) become extremely dynamic. You can modify many variables or members in one function. Put another way, you can return more than one thing from a function.
More on the CPU
Through the course, I also came to appreciate the role the CPU plays when working with memory. Eventually, just like I did, you’ll ask:
Why not just pass everything by value all the time? Wouldn’t that be the simplest approach?
Passing by value takes a toll on memory. C comes to the rescue as it lets you allocate memory more efficiently using malloc() and free(). Like I said, constantly passing by value takes a toll on memory, which is where pointers prioritize getting the CPU more involved so some of the stress can be taken off memory. Ultimately, finding this balance between memory storage and CPU usage is a kind of chess game that embedded engineers face, and it’s something that I’m excited to get into.
The ultimate trade-off:
Using pointers is more memory efficient, but requires more work from the CPU.
Passing by value is less memory efficient, but potentially faster for small structs due to simpler CPU-level instructions.
The End
Pointers aren’t magic—they’re just how computers connect the dots, literally. Once you see memory as one long street of addresses and pointers as the signposts, everything starts making sense. From linked lists to hashmaps, it’s all just clever memory navigation. C lays it bare: no safety nets, full control. And yeah, that means the power to build elegant systems—or blow your foot off with a buffer overflow. But that’s the thrill. Understanding pointers doesn’t just level you up—it unlocks the map to the machine.