By this point you should be wondering about the weird, seemingly inconsistent use of arrays (and strings) in C. It's puzzling until you learn one little secret. This is where this secret is unveiled.
Everything is explained by this single fact: when we declare an array
a is the array's ﬁrst element, but
a by itself is the address in memory where the array sits. The
a[n] operator works by adding to an address
a the result of
n times the size of the type of
a and using that address. In this way it's easy to translate array references to simple machine code instructions. This is why it's not a good idea to do array range-checking in C (there wouldn't be a point in designing something so fast if we had an extra couple of instructions after it).
This is also why writing
a is not an error. There are times when you want to refer to an array by its address.
strcpy() needs the address of the target string so it can store its results, hence we used just
s in the example program above.
Finally, this also explains why it's okay to declare an array as
int b and sometimes refer to it as just
b. Multi-dimensional arrays are thought of as arrays of arrays. In this case, we have a 10-element array of 2-element int arrays. So
b refers to the address of the fourth (remember, they start at zero!) 2-element
int sub-array. This coincides with the address of element
b, just like
b is the address of the array's ﬁrst element,
b. But beware: an address is not an element! Unless you specify all indices, you can't access a single element, and you'll get compiler errors.