CC Explainer
C · 2 · Memory & Pointers10 / 35 · 29%

Pointer Arithmetic & Arrays vs Pointers

Why a[i] is literally *(a + i), and where arrays stop behaving like pointers.

Examples: a[i], p + n, decay, sizeof

shortcuts: ← prev · → next · M mark
1

Indexing Is Arithmetic

The compiler rewrites a[i] as *(a + i). Both forms are identical.

Example
example
int a[4] = {10, 20, 30, 40};
printf("%d %d\n", a[2], *(a + 2));  // 30 30
printf("%d\n", 2[a]);               // 30 — legal, and awful
2

Scaling by Element Size

p + 1 moves sizeof(*p) bytes, not one byte.

Example
example
int    *pi = a;      // +1 moves 4 bytes
char   *pc = (char*)a; // +1 moves 1 byte
double *pd;            // +1 moves 8 bytes

ptrdiff_t gap = &a[3] - &a[0];  // 3, not 12
int* p0x7ffd10int x = 4242
stride = sizeof(element)
3

Array Decay

Passed to a function, an array becomes a bare pointer — the length is lost.

Example
example
void f(int arr[]) {
    printf("%zu\n", sizeof arr);  // 8 — the pointer size!
}

int main(void) {
    int a[10];
    printf("%zu\n", sizeof a);    // 40 — the real array
    f(a);
}
TIP
Always pass the length alongside the pointer: f(int *arr, size_t n).
4

Multi-Dimensional Arrays

int m[3][4] is contiguous — 12 ints in a row, not an array of pointers.

Example
example
int m[3][4];
m[1][2] = 7;                 // == *(*(m + 1) + 2)
int *flat = &m[0][0];
flat[1 * 4 + 2] = 7;         // same cell

void g(int rows, int cols, int m[rows][cols]); // C99 VLA parameter
Interview question
Difference between int **pp and int m[3][4]?