Pointer & Array Arithmetic in C
After a decade of working with TypeScript, my pointer arithmetic skills had become rusty. While I had spent the last few months working with C and C++, my experience is that organizing lessons learned—and relearned—helps fill gaps, and writing an article is a great way to reinforce that. This isn’t a deep dive into pointers; plenty of great in-depth articles already exist. Instead, it’s my reflection on the topic—perhaps someone else will find it useful too.
This article takes the following small piece of C code as a starting point:
int arr[3] = {10, 20, 30};
int *p = arr;
Defined array with three elements, and created a pointer storing the address of the array.
An array decays into a pointer in most expressions...
printf("%d\n", *(p + 1)); // prints 20
printf("%d\n", arr[1]); // prints 20
p+1
moves the address p
by 4 bytes because p
is an int*
. Array indexing is simply syntactic sugar for pointer arithmetic and dereferencing.
int
is not necessarily 4 bytes, but it is on most systems. For simplicity, assuming that from now on....but an array is not a pointer
The size of an array gives the size of the array, not the size of the address, as a pointer would.
printf("%lu\n", sizeof(arr)); // Prints 12 (if int is 4 bytes)
printf("%lu\n", sizeof(p)); // Prints 8 (pointer size on 64-bit)
sizeof(p)
isn’t necessarily 8 on all systems—it depends on whether the system is 32-bit or 64-bit. A pointer is typically 8 bytes on a 64-bit system or 4 bytes on a 32-bit system. For simplicity, this demonstration assumes a 64-bit system.The reference operator gives a different type
printf("%p\n", p); // Address of arr[0]
printf("%p\n", &arr); // Address of the whole array
While both prints the same address, incrementing them leads to different results:
printf("%p\n", p+1); // Address of arr[1]
printf("%p\n", &arr+1); // The first address after array
The first expression shifts by sizeof(int)
which is 4. In the second expression, since &arr
is of type int(*)[3]
increments the address by sizeof(arr)
, the size of the array which is in this case is 12.
Arrays cannot be reassigned
p = &arr[2]; // allowed
arr = p; // ERROR
arr = {40,50,60}; // ERROR
An array cannot be reassigned to a pointer, further proving that an array is not a pointer.
arr
is not a pointer; it’s an array name, which most of the time acts as a constant pointer to the first element. The example attempts to modify an immutable address.
Summary
Pointers and arrays in C are closely linked but not interchangeable. While arrays decay into pointers, they retain some properties.