Lesson 1 · 1 of 20
Pointers to pointers and arithmetic · C
Walk C arrays with pointer arithmetic, subtract pointers, and use a pointer to a pointer so a function can change where another pointer points.

Pointer arithmetic counts in elements, not bytes: if p points at prices[0], then p + 2 points at prices[2] and *(p + 2) is the same as prices[2]. The compiler multiplies by the size of the type, which is why (char *)(p + 1) - (char *)p gives 8, the bytes in a double.
Subtracting two pointers into the same array gives the number of elements between them, as a ptrdiff_t (printed with %td). (prices + n) - p is 5, and cheapest - prices turns a pointer into its index. Pointing one past the last element, like prices + n, is allowed for comparisons but not for reading with *.
A function gets copies of its arguments. For find_cheapest to change the cheapest pointer in main, it receives its address, &cheapest, and the parameter is a pointer to a pointer, double **. Inside, *cheapest is main's pointer and **cheapest is the price it points at.
The most common use of ** is a list of strings: shops is an array of const char * ending in NULL, just like argv. const char **s walks the list: *s is each string and **s its first letter.
In DMarlon Studio, you write this program in the Console target and build and run it with one click (F9).
Code · main.c
#include <stdio.h>#include <string.h>// Receives the address of a pointer and makes it point at the cheapest price.void find_cheapest(double *prices, int n, double **cheapest) { *cheapest = prices; for (double *p = prices + 1; p < prices + n; p++) if (*p < **cheapest) *cheapest = p;}int main(void) { double prices[] = {4.50, 3.20, 5.10, 2.95, 3.80}; int n = sizeof prices / sizeof prices[0]; // Pointer arithmetic: p + 2 moves two elements, not two bytes. double *p = prices; printf("First: %.2f, third: %.2f\n", *p, *(p + 2)); printf("Bytes from p to p + 1: %td\n", (char *)(p + 1) - (char *)p); printf("Elements from start to end: %td\n", (prices + n) - p); double *cheapest = NULL; find_cheapest(prices, n, &cheapest); printf("Cheapest: %.2f at index %td\n", *cheapest, cheapest - prices); // A list of strings is an array of pointers: char ** walks through it. const char *shops[] = {"Bakery", "Market", "Kiosk", NULL}; for (const char **s = shops; *s != NULL; s++) printf("Shop %td: %-7s first letter %c, %zu letters\n", s - shops, *s, **s, strlen(*s)); const char **second = shops + 1; printf("Through **: %s starts with %c\n", *second, **second); return 0;}Output · cc main.c -o main && ./main
First: 4.50, third: 5.10 Bytes from p to p + 1: 8 Elements from start to end: 5 Cheapest: 2.95 at index 3 Shop 0: Bakery first letter B, 6 letters Shop 1: Market first letter M, 6 letters Shop 2: Kiosk first letter K, 5 letters Through **: Market starts with M
Key points
p + imovesielements;*(p + i)isp[i].- Subtracting pointers gives elements, printed with
%td. - To change a pointer from a function, pass
&pointerand take aT **. - Walk an array of strings with
char **untilNULL.
Exercise
Write find_dearest with the same shape as find_cheapest and use both to print the highest price, the lowest price and how many elements apart they are.