CIntroduction to Pointers

Introduction to Pointers

Pointers are the feature C is most famous for — and the one that scares beginners the most. That reputation is a little unfair. Once the core mental model clicks, pointers are not mysterious at all: they are just variables that store an address instead of a value. Everything else in this topic — arrays, strings, dynamic memory, linked structures, function callbacks — is built on top of this one simple idea.

What a pointer actually is

Every piece of data your program uses lives somewhere in memory, and every location in memory has a numeric address, much like every house on a street has a street number. A normal variable, say int age = 30;, is a labeled box that holds the value 30. A pointer is a different kind of box: instead of holding 30, it holds the address of the box that holds 30. We say the pointer "points to" that other variable.

C
#include <stdio.h>

int main(void) {
    int age = 30;      // a normal variable holding a value
    int *p = &age;     // a pointer holding age's address

    printf("age            = %d\n", age);
    printf("address of age = %p\n", (void *)&age);
    printf("value of p     = %p\n", (void *)p);
    printf("value pointed to by p = %d\n", *p);
    return 0;
}
Two boxes, one arrow
Picture two boxes side by side. The first box is labeled `age` and contains `30`. The second box is labeled `p` and contains an arrow pointing at the first box — that arrow is really just the numeric address of `age` stored inside `p`. Nothing more exotic is happening than that.
Why C exposes raw memory addresses

Many higher-level languages hide memory addresses from you completely. C deliberately does not, for a few reasons that made sense given what C was designed for — writing operating systems, compilers, and other software that needs to be fast and to control hardware directly:

  • Control — pointers let a program manipulate exactly the byte or word of memory it needs to, which matters when talking to hardware registers, device drivers, or tightly packed data formats.

  • Efficiency — passing a small address around is far cheaper than copying a large struct or array every time it is handed to a function.

  • Building blocks — arrays, strings, dynamic memory allocation, and data structures like linked lists and trees are all, under the hood, expressed in terms of pointers. Understanding pointers is the key that unlocks the rest of C.

Why pointers feel hard (and why that fades)

Pointers introduce a genuinely new idea — a variable whose value is "meaning" only in relation to another variable's location — and that indirection takes a moment to click. On top of that, the same symbol, *, is reused for two different jobs (declaring a pointer vs. dereferencing one), which is a real source of early confusion and is covered in detail on the next page. Add in the fact that pointer mistakes tend to produce confusing crashes rather than clean error messages, and it is easy to see why pointers get a scary reputation.

In practice, the reputation is overstated. There is really only one idea to internalize: a pointer holds an address, and following that address (dereferencing) gets you to the value stored there. Every pointer topic in this section — arithmetic, arrays, strings, pointers-to-pointers, function pointers — is a variation on that one theme, not a new concept from scratch.

How to read the rest of this section
Keep the "box with an arrow" picture in mind as you work through declaration and dereferencing, pointer arithmetic, and the relationship between pointers and arrays. Almost every pointer bug you will ever meet — segmentation faults, wild pointers, dangling pointers — comes down to the arrow pointing somewhere it should not.