In C, a multi-dimensional array for which you know the size in advance can be iterated through how we'd expect (i.e. using double subscript notation m[i][j]):
void printMatrix(float m[SIZE][SIZE]){
int i,j;
for(i=0; i<SIZE; i++){
for(j=0; j<SIZE; j++)
printf("%f ", m[i][j]);
printf("\n");
}
printf("\n");
}
(I'm using all square matrices for simplicity). But the signature for printMatrix has to specify the size of the matrix (though, the first dimension can be left out). That's because when you have a multi-dimensional array it's actually just an ordinary array with each row one after another. When the compiler compiles m[i][j] it actually translates it into something like m[i*n+j], and you have to specify the size in advance so it knows what n is.
Now, if you have a dynamically allocated multi-dimensional array (or if you simply want to write a function that doesn't have to know the size in advance), you essentially have to do some of that compilation yourself. printMatrix becomes:
void printMatrix(float *m, int n){
int i,j;
for(i=0; i<n; i++){
for(j=0; j<n; j++)
printf("%f ", m[i*n+j]);
printf("\n");
}
printf("\n");
}
And you can allocate m with:
float *m = (float*) calloc(d*d, sizeof(float));
I agree this is a good method when the array size is not known in advance.
But, for dynamically allocated multi-dimensional arrays--whose size is known in advance--there is a better way.
Instead of pointing to a matrix with a pointer of type (float *), you can define a more exotic pointer like this
float (*p)[SIZE];
and then you allocate storage for p, using malloc or whatever you like. Now the first version of printMatrix will work just fine when you call printMatrix(p).
I prefer this method because it helps detect data-type mismatches. For example, let's say someone accidentally uses printMatrix to print an array v[] of floats, where v[] represents a vector, instead of a matrix. The second version of printMatrix would unwittingly allow
printMatrix(v,SIZE);
and this would probably cause a hard-to-track-down memory access violation at run-time.
But, in the first version of printMatrix, trying to call printMatrix(v) would cause an easy-to-spot compliation error because v does not have type float[][SIZE]