Step 7 of 10
Pointers to pointers
A pointer is itself a variable, so it has an address too. A pointer to a pointer (int **pp, read "pointer to pointer to int") stores that address. It sounds abstract, but there's one very practical reason to use it:
When a function must change which address the caller's pointer holds, it needs the address of that pointer, for the same reason a function needs &x to change an int.
#include <stdio.h>
void skip_digits(const char **p) {
while (**p >= '0' && **p <= '9') {
(*p)++;
}
}
int main(void) {
const char *text = "2024 was a leap year";
skip_digits(&text);
printf("[%s]\n", text);
return 0;
}
[ was a leap year]
Unpacking the stars
Inside skip_digits, p has type const char **:
pis the address ofmain'stextvariable.*pismain'stext(aconst char *), so(*p)++moves the caller's pointer forward.**pis the character thattextcurrently points at.
The parentheses in (*p)++ matter. *p++ would move p itself (the local copy of the address) instead of the caller's pointer, because ++ binds tighter than *.
After the call, main's text points into the middle of the same string. Nothing was copied; only the pointer moved.
Where you'll see this
Functions that allocate memory and hand it back through a parameter, functions that parse text and advance the caller's position, and linked-list code that changes the head pointer all use double pointers.
Your turn: write void advance(const char **s) that moves the caller's string pointer past any leading spaces. After advance(&p) with p pointing at " go", p should point at "go".