Lesson 89 +10 XP

C-Style Arrays and Pointer Arithmetic

C-Style Arrays and Pointer Arithmetic

The built-in array is the classic container, but it hides a surprise: arrays and pointers are intimately connected.

Fixed-size built-in arrays

int arr[3] = {10, 20, 30}; created a fixed-size array. Its size is set at compile time and cannot change. (Already we keep it inside the same scope, or it's hard to tell.)

Arrays decay into pointers

An array name acts, in most uses, like a pointer to its first element. Passing it to a function decays it to that pointer:

int arr[3] = {10, 20, 30};
int* ptr = arr;   // ptr points at arr[0]

Once you have such a pointer, the array's size is gone - the pointer doesn't know how many elements follow.

Pointer arithmetic

You can do arithmetic on a pointer. Adding 1 moves forward by one element (not one byte) because the type's size decides the step:

cout << *ptr;         // 10  (arr[0])
cout << *(ptr + 1);   // 20  (arr[1])
cout << ptr[2];       // 30  (arr[2])

In fact, arr[1] is literally the same as *(arr + 1). Array indexing is just sugar for pointer arithmetic.

Why prefer std::array / std::vector

  • With a vector or array, the size stays known (.size()).
  • .at() catches out-of-bounds mistakes with exceptions.
  • No surprise decay, no falling back to memory-gymnastics.
  • You can forget the raw pointer to pointer gymnastics.

Rule: fixed size -> std::array; dynamic size -> std::vector.

TL;DR

  • Built-in arrays have a fixed compile-time size.
  • An array name decays to a pointer to its first element.
  • arr + 1 steps to the next element; *(arr + 1) equals arr[1].
  • Pointers don't carry the array's size, so sizeof no longer helps.
  • Prefer std::array / std::vector: size stays known and access is safer.