Arrays in C: Part 1
An array is a contiguous block of memory sized to hold N elements of a particular type (except for void, incomplete, or function types). Arrays are 0-origin, meaning that elements of an N-element array are numbered 0..N-1. Example:
for (i = 0; i < 9; i++)
arr[i] = ...;
In C (and most C-derived languages), multidimensional arrays are treated as arrays of arrays, e.g.:
#define ROWS ...
#define COLS ...
Again, this describes a contiguous chunk of memory sized to hold ROWS * COLS integers.
Simple so far, right?
Well, here's where it stops being simple. When an array identifier appears in most contexts, its type is converted from "array of T" to "pointer to T", and its value is set to point to the first element in the array. The only times this conversion doesn't happen is when the array identifier is an operand of either the address-of (&) or sizeof operators. When you hear someone say something like "arrays are just pointers" or "arrays and pointers are the same thing," they're garbling this concept. Arrays are not pointers, but the type of the array identifier is converted to a pointer in most contexts.
Also, array subscripting is done in terms of pointer arithmetic. The expression a[i] is functionally equivalent to *(a+i); that is, i is an offset from the base address a (this is why array indices go from 0 to N-1 instead of from 1 to N). It also means that array indexing is commutative; a[i] == i[a], although you'll rarely see the second form in code that isn't deliberately obfuscated.
Arrays are lvalues, but non-modifiable. In short, that means the following is illegal:
int a, b;
a = b;
You cannot assign a new value to an array object.