arrays and multidimensional arrays
An array is a row of identical mailboxes standing side by side, all the same size, numbered from 0. Instead of declaring ten separate variables for ten scores, you declare one array of ten and refer to each slot by its index. The slots sit next to each other in memory, which is what makes indexing fast and predictable.
You declare an array with a type, a name, and a size in brackets: 'int scores[5];' makes five int slots, accessed as scores[0] through scores[4]. The index counts from 0, so the last valid index is the size minus one. The elements are contiguous in memory: scores[i] sits at the base address plus i times the size of one int. A multidimensional array is an array of arrays: 'int grid[3][4];' is 3 rows of 4 columns, addressed as grid[row][col], and it is laid out row by row in memory (row-major order). C does NOT store the length anywhere alongside the array, and it does NOT check your indices — going out of bounds reads or writes neighboring memory.
Why this matters and the central caveat: arrays are the bedrock of strings, buffers, and tables, but their lack of bounds checking is one of C's sharpest edges. An off-by-one error or an index past the end is a buffer overflow — undefined behavior that may corrupt data, crash, or open a security hole. Two more honest details: in most expressions an array's name decays to a pointer to its first element (so the length is lost when you pass it to a function — you must pass the length separately), and sizeof on the array itself gives the whole array's byte size, not on a pointer to it.
int scores[5] = {90, 85, 70, 60, 95}; int third = scores[2]; /* index from 0: this is 70 */ int grid[2][3] = {{1,2,3},{4,5,6}}; int cell = grid[1][2]; /* row 1, col 2: this is 6 */ /* scores[5] would be out of bounds: undefined behavior */
Indices run from 0 to size-1; the 2D array is stored row by row. Accessing scores[5] is past the end — undefined behavior, not a caught error.
C does not store an array's length and does not bounds-check indices — going out of bounds is undefined behavior (a buffer overflow). When passed to a function an array decays to a pointer and the length is lost, so you must pass the length yourself.