I was just wondering why it is allowed to omit the leftmost index of a multidimensional array when passing the array to a function ? Why not more than one indexes? And how does the compiler find out the size with one index omitted ?
Other answers described how the C standard handles array to pointer conversion and how this affects the function declaration, but I feel they didn't go into the why, so here I go...
In C, arrays stand for tightly packed elements in memory.
A -> _ _ _ _ _ _ ...
i: 0 1 2 3 4 5 ...
In the above example, each of the array elements is 1 _
wide. To find the i-th element, we thus have to go to the i-th address. (Note that the leftmost dimension (the size) doesn't matter here)
Now consider a multidimensional array:
B -> [_ _ _][_ _ _][_ _ _][_ _ _]...
i: 0 0 0 1 1 1 2 2 2 3 3 3
j: 0 1 2 0 1 2 0 1 2 0 1 2
^first row ^third row
To find the offset of A[i][j]
we need to jump over i rows (3*i) and then over j elements -> (3*i + j). Note how the size of the first dimension is also not needed here.
It should be clear by now then, that the leftmost size isn't needed when using the array, it is only needed when you create it.
Since there is no need to give the dimension of the leftmost index, then why not give it anyway, for completeness sake? After all, this is what is done in the Pascal programming language (a C contemporary).
Well, most functions that operate on arrays work the same for all possible array lengths, so specifying the size would only hurt your ability to reuse them.
for example, why do
int sum(int arr[10]){
int s = 0, i;
for(i=0; i<10; i++){
s += arr[i];
}
return s;
}
When you can do this instead:
int sum(int arr[], int n){
int s = 0, i;
for(i=0; i<n; i++){
s += arr[i];
}
return s;
}
As for omitting more then one dimension, this isn't possible when using normal multidimensional arrays (because you need to know the dimension to know when the first row ends and the second starts). However, if you are willing to spend some (little) extra memory for scratch space, it is perfectly possible to use pointers to pointers instead: http://www.eskimo.com/~scs/cclass/int/sx9b.html