Because of 0 indexing, the nth element has index n-1.

A trick I learned is that when unsure, consider a small test case, like 2x2 array. Since the logic must work for all cases, if it works for 2x2 it should work for nxm. This trick is generally applicable. It is much easier to manipulate small amounts of data in our heads / on paper than it is to consider the actual data involved.

The equations in the above link should make clear what is going on. But if not, I shall make an attempt:

If you declare

char a[10][2];

Then a decays into a pointer to the

*first row*, which is an array of length 2.

The declaration

char (*x)[2];

Is declaring a pointer to a data type, but instead of char or int or float, it is pointing to a char array of length 2. Now there is an equivalence between a and x, and you can assign a to x and then use x like you would a in places where a decays to a pointer. Keep mind this condition: in places where a does

*not* decay into a pointer to the first row, a is a very different beast to x.

Under the hood, a 2D array is realised in 1D memory address by concatenating the rows. So really a 2D array is a 1D array containing 1D arrays as elements, and a[n][m] is really saying "give me the nth element of a, and give me the mth element of that element". This nested-1D-array representation of multidimensional arrays extends to high dimensions.

Understanding this nested-1D-array representation of multidimensional array is essential to be able to dynamically allocate multidimensional arrays in runtime, by constructing a suitable array of pointers.

If you have done differential equations, this approach should be similar to how you rewrite high order derivatives as a set of equations using only first derivatives.

**Edited by freespace, 17 January 2010 - 11:35 AM.**