Skip to content
Pointers Basics
step 1/5

Reading — step 1 of 5

Learn

~3 min readFunctions and Pointers

Pointers Basics

This is the lesson C exists to teach. A pointer is a variable whose value is a memory address — and once addresses are values you can store, pass, and do arithmetic on, you can build every data structure and every API in computing. Every language you've used has pointers under the hood; C hands you the actual thing.

Two operators

int x = 42;
int *p = &x;      /* & — "address of":  p now holds WHERE x lives   */
printf("%d\n", *p);   /* * — "value at": follow p to its target → 42 */

*p = 99;          /* write THROUGH the pointer…                      */
printf("%d\n", x);    /* 99 — x changed. Same bytes, two names.      */

Read int *p as "p is a pointer to int." &x produces x's address; *p (dereferencing) follows the stored address to the actual bytes. That's the entire mechanism — two operators, inverse of each other (*&x is just x).

Draw it once, in boxes, with made-up addresses:

   x  @0x7ffc0010: [   42  ]
   p  @0x7ffc0018: [0x7ffc0010]   ──points to──▶  x

p's value is x's location. Every pointer situation you'll ever debug reduces to this diagram; when confused, draw the boxes.

Why: the exception to copy-by-value

Last lesson ended on a cliffhanger — functions get copies, so how does anything ever modify its caller's data? Like this:

void doubleIt(int *n) {
    *n *= 2;              /* follow the address, change the original */
}

int x = 5;
doubleIt(&x);             /* pass x's ADDRESS (a copy of the address — fine!) */
printf("%d\n", x);        /* 10 */

The address is itself copied — but a copy of an address points to the same place. This is precisely scanf("%d", &x) — you've been doing pointer calls since chapter 1; now the syntax has a mental model. It's also how a function "returns" multiple results: pass several addresses, fill them all.

NULL and the crash you'll come to respect

A pointer that points nowhere holds NULL:

int *p = NULL;
if (p != NULL) {          /* guard before every dereference of a maybe-NULL */
    printf("%d\n", *p);
}

Dereferencing NULL crashes — segmentation fault — and among C crashes it's the polite one: immediate, loud, at the guilty line. The impolite ones (dangling pointers into freed or dead memory) sometimes work, which is worse. Two disciplines from day one: initialize pointers (to something real or to NULL, never garbage), and guard maybe-NULL pointers before following them. The if (p) truthiness idiom from Conditionals is this guard in its native habitat.

Your exercise: Swap

The canonical pointer proof — a function that exchanges two variables:

void swap(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

/* in main: */  swap(&x, &y);

Every * in the body matters: tmp = *a saves the value at a; the assignments move values between the targets. (A starred-less a = b would just shuffle the local copies of the addresses — compiles, does nothing visible, a perfect tiny lesson in the difference.) Without pointers this function is impossible in C — swap(x, y) would swap two copies and change nothing. That impossibility, solved, is why this exercise is the pointer kata. When it passes, draw the boxes one more time and check the picture matches what happened; from here on — arrays, strings, malloc, every struct API — it's this diagram all the way down.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…