Intuitively Obvious to the Most Casual Observer

A pointer is just a number

By far the most frustrating part of learning C - and teaching it - is understanding pointers. For some reason, they present a monad-sized roadblock to learning the language. To a certain extent, this is understandable, since the concept of pointers is one of the few truly novel ideas in programming languages - there’s no way to emulate pointers in C from the objects you’ll already have learned. That sort of novelty is expected to be difficult to learn.

But it’s worse than that - most people learning C for the first time (often coming from Java or, worse, python et al) find it nearly impossible to understand the difference between the pointer and the object it points to. That’s not because of anything inherently complex about pointers, but rather because most people (myself, until today, included) approach teaching them wrong.

Experienced programmers (defined here as “those comfortable with pointers”) consider a pointer to be a surrogate for the object it points to. Operations on that object are performed through the pointer. Thus, when teaching, it can be tempting to mention first how a pointer allows you to access an object. Which is true, but it’s not what a pointer is - and that’s the information someone new to a concept needs most.

The whole idea of confusing a pointer with what it points to can be avoided simply by emphasizing the white lie that a pointer has nothing whatsoever to do with what it points to. It is first and foremost a number - we’re just storing a special value in it.

int main() {
    struct big_data data = …;
    int p = &data;

void my_op(int p) {
    // use data

And now all is clear. Of course, you wouldn’t actually write int in a program, but here it serves its educational purpose.

This is a good example of how teaching is a skill fundamentally different from just using knowledge. It is not sufficient even to have a particularly deep understanding of what it is you’re doing - you must explain it in a way that often seems upside-down to those accustomed to practice. The art is in doing this with as few lies as possible. (Given the quirks of C’s pointer syntax, it may not be possible to do that with none - the intermediate code using int instead is possibly necessary.)