Without missing the literals on Sun and Microsoft, this is what I remember from my days C. I hope this helps.
To make it simple, if we just think in two dimensions - arrays can be represented as a two-dimensional array and an array of pointers. In code, this is int x [15] [20]; int * y [15];
In this example, x [5] [6] and b [5] [6] are valid syntactically and end with a reference to a single int.
Saying this, x is a true two-dimensional array: after creating it, 300 locations (which can contain int) will be created, and you can use the well-known subscript convention to access this rectangular (with 15 rows and 20 columns) array, where you can go to x [row, col] by calculating (20 * row) + col.
However, in case y, when the structure is defined, only 15 pointers are allocated, but not initialized. (Initialization must be done explicitly)
There are advantages and disadvantages of this approach (an array of pointers or an array of arrays) or a jagged array, as it is called):
Advantage:
The rows of this array can have different lengths, that is, each y element should not point to twenty ROW elements; one element can point to 2 elements, the second element can point to 3 elements and from third to zero elements, etc.
Disadvantages:
However, in the best case scenario, if each element of y points to a twenty-element array, then 300 integer locations will be reserved, plus ten cells for additional pointers.
From the point of view of the current example, examples of C sharp examples given above (in one of the previous posts) should be given.