C Pointer Arithmetic & Arrays
Two Friends, One Address
Here's one of C's most mind-bending facts: an array name is secretly a pointer to its first element. When you write int arr[5];, the name arr is essentially &arr[0] β the address of locker 0.
This means you can use pointer syntax on arrays and array syntax on pointers. They're interchangeable in most contexts. The expression arr[i] is literally rewritten by the compiler as *(arr + i).
But they're not identical. An array name is a constant β you can't make it point somewhere else. A pointer variable can be reassigned. Think of the array name as a permanent sign bolted to locker 0, while a pointer is a movable sticky note.
Array Name as Pointer
How Pointer Arithmetic Works
When you add 1 to a pointer, it doesn't move forward 1 byte. It moves forward by the size of the type it points to. An int* moves 4 bytes, a double* moves 8 bytes, a char* moves 1 byte.
This is what makes pointer arithmetic so elegant β you think in elements, not bytes. ptr + 3 means "3 elements ahead," regardless of how many bytes that actually is.
You can also subtract two pointers of the same type. The result is the number of elements between them β again, not bytes.
Pointer Arithmetic Steps by Type Size
sizeof(type), not by 1 byte. When you do int *p; p + 1;, the address increases by 4 (the size of an int), not by 1. This is the most common misconception. If you cast to char* and add 1, then it moves by 1 byte β because sizeof(char) is 1.Traversing an Array with a Pointer
Instead of using an index variable, you can walk a pointer through an array. Start at the beginning, increment with ptr++, and stop when you reach the end. This is how many C standard library functions work internally.
Traversing an Array with a Pointer
The Equivalence: arr[i] == *(arr + i)
This is the fundamental identity of C arrays and pointers. The compiler translates every arr[i] into *(arr + i). Because addition is commutative, this means arr[i] is also *(i + arr), which means β believe it or not β i[arr] is valid C. (Please never write that in real code.)
Array of Strings
A common pattern in C is an array of pointers to characters β essentially an array of strings. Each element is a char* pointing to a string literal. This is exactly what argv is in int main(int argc, char *argv[]).
Array of Strings (char*[])
Pointer to Array vs. Array of Pointers
The syntax can be confusing:
int *arr[5]β an array of 5 pointers to int (5 sticky notes)int (*arr)[5]β a pointer to an array of 5 ints (1 sticky note pointing to a row of 5 lockers)
The parentheses make all the difference. When in doubt, read declarations from the variable name outward: arr is a *(pointer) to [5](array of 5) int(integers).