This is going to be a bit abstract but it’s honestly really worth trying to get your head around if you want a good solid foundation in pointers and referential semantics in general.

Pretty much everybody starts their programming career by doing some Hello World stuff and then moving on to some simple variable manipulation like this:

If you run this code you’ll see that b is equal to 2 but a is still equal to 1. This is known as value semantics or sometimes copy semantics. When we do int b = a we’re making b store a copy of the value stored in a. Subsequent changes to b will have no effect on a.

In reference semantics we’d do this instead:

This would result in both a and *b having a value of 2. Here, a is set to 2 indirectly and implicitly through the reference provided by b.

You can read about pointer operators if you don’t understand all those * and & thingies but what’s important here is the idea of references.

In value semantics we’re dealing with objects directly but in reference semantics, a reference provides a link to another thing. The referrer refers to the referent. C pointers are one example of a reference but there are other ways to implement reference semantics - in other words reference is a generic term and pointer is a specific example of a reference.

Referencing in turn is a specific case of indirection, the process of gaining access to one thing via another. The opposite of referencing is dereferencing. There’s more info in my article on C’s pointer syntax

That’s the top and bottom of references really but if you think about them, they do open up your mind to some fairly deep observations about the world. For example here’s a question about numbers.

Finally, here are a couple of subtleties. See if you can answer them yourself before reading my take on them.

What’s the difference between a variable and a pointer? Both are ‘indirections’. The defining difference is that a pointer is a variable whose value is an address which further indirects to a value whereas a variable indirects to a value in a single step.

What’s the difference between an address and a pointer? Not very much really. Both can be used in the same places e.g.

int value;
int i = *(&value);

is equivalent to

int value;
int i;
int *ptr = &value;
i = *ptr;