Arrays & Strings · beginner · ~10 min

Arrays

Declare, index, and walk a fixed-size array.

Overview

An array is a contiguous block of memory holding N values of the same type. The compiler knows the size at declaration (int a[10]), and you access elements by index a[i] where i is 0..N-1. Arrays don't carry their length around — you must track it.

Why it matters

Arrays are how C represents sequences: lists of numbers, characters in a string, pixels in an image, samples in an audio buffer. Most other data structures (vectors, ring buffers, hash tables, heaps) are built on top of arrays.

Core concepts

Zero-indexed. Element 0 is the first; element N-1 is the last. a[N] is one past the end — accessing it is undefined behaviour. Decay. When an array name appears in an expression (not in sizeof or &), it 'decays' to a pointer to the first element. This is why void f(int a[]) and void f(int *a) are equivalent. Fixed size. A plain array's size is fixed at compile time. For runtime-sized arrays, you allocate with malloc and treat the pointer as an array.

Syntax notes

int a[5] = {1, 2, 3, 4, 5};      // declare + initialise
int b[5] = {0};                   // all zeros
int c[] = {10, 20, 30};           // size inferred (= 3)
size_t n = sizeof a / sizeof a[0]; // number of elements (only works on real arrays, not decayed pointers)

Lesson

An array is a contiguous block of elements of the same type. Declared int a[N];, indexed a[i], where i ranges from 0 to N-1. The compiler does not bounds-check at runtime — accessing a[N] is undefined behaviour.

Arrays don't carry their size around in C. When you pass an array to a function, it decays to a pointer to the first element; the size has to be passed separately.

Code examples

int a[5] = {10, 20, 30, 40, 50};
for (size_t i = 0; i < 5; i++) printf("%d ", a[i]);

Common mistakes

  • Off-by-one: indexing a[len] after a loop that ends at len.
  • Returning a pointer to a local array — the storage vanishes.

Debugging tips

If an array seems to hold wrong values, print every element in a loop. AddressSanitizer (-fsanitize=address) detects out-of-bounds accesses at runtime. Index variables should match the array's intended range — if a has 10 slots, your loop variable goes from 0 to 9, never 10.

Memory safety

Writing past the end of an array (a[N], a[N+1], ...) silently corrupts whatever happened to be after the array in memory — often a return address, leading to crashes that look unrelated to the actual bug. Always check i < N before a[i]. Use memcpy rather than hand-rolled loops when you can — it has clearer bounds.

Real-world uses

Pixel buffers, audio samples, lookup tables, hash tables, packet bytes, file content read into memory, sensor history. Every fast inner loop in numerical code is an array traversal.

Practice tasks

  1. Sum an int array. 2. Find the maximum and its index. 3. Reverse an array in place. 4. Count how many elements equal a given value. 5. Write a function void print_array(const int *a, size_t n).

Summary

Arrays are contiguous, fixed-size, same-type. Track their length yourself, index strictly in [0, N), and don't be surprised when arrays decay to pointers when passed to functions. They are the backbone of nearly every C data structure.

Practice with these exercises