Without going through the reams of literature on the Sun and Microsoft sites, this is what I remember from my C days. Hope this helps.
To make it simple, if we just think in 2 dimensions - Arrays can either be represented as a two-dimensional array and an array of pointers. In code this amounts to
int x[15][20];
int *y[15];
In this example, x[5][6] and b[5][6] are both valid syntactically and end up referring to a single int.
That being said, x is a true two-dimensional array: Once you create it , there will be 300 locations (that can contain int) that have been set aside, and you can use the well known subscript convention to access this rectangular (with 15 rows and 20 columns) array where you can get to x[row,col] by calculating (20 * row) + col.
However in case of y, while the structure is being defined, only 15 pointers are allocated, but not initialized. (Initialization will need to be done explicitly)
There are advantages and disadvantages of this approach (pointer array or "array of arrays" or jagged array as it is called):
Advantage:
The rows of this array can be of different lengths i.e. each element of y does not need to point to a twenty-element ROW; one element may point to a 2 elements, 2nd element may point to 3 elements, and 3rd to zero elements and so on.
Disadvantage:
However given a best case scenario, if each element of y does point to a twenty-element array, then there will be 300 integer locations set aside, plus ten cells for the pointers which is additional.
From a current example perspective, the C sharp examples given above (in one of the previous posts) should suffice.