given the following function signature:
void readFileData(FILE* fp, double inputMatrix[][], int parameters[])
this doesn’t compile.
and the corrected one:
void readFileData(FILE* fp, double inputMatrix[][NUM], int parameters[])
my question is, why does the compiler demands that number of columns will be defined when handling a 2D array in C? Is there a way to pass a 2D array to a function with an unknown dimensions?
thank you
C doesn’t have any specific support for multidimensional arrays. A two-dimensional array such as
double inputMatrix[N][M]is just an array of lengthNwhose elements are arrays of lengthMof doubles.There are circumstances where you can leave off the number of elements in an array type. This results in an incomplete type — a type whose storage requirements are not known. So you can declare
double vector[], which is an array of unspecified size of doubles. However, you can’t put objects of incomplete types in an array, because the compiler needs to know the element size when you access elements.For example, you can write
double inputMatrix[][M], which declares an array of unspecified length whose elements are arrays of lengthMof doubles. The compiler then knows that the address ofinputMatrix[i]isi*sizeof(double[M])bytes beyond the address ofinputMatrix[0](and therefore the address ofinputMatrix[i][j]isi*sizeof(double[M])+j*sizeof(double)bytes). Note that it needs to know the value ofM; this is why you can’t leave offMin the declaration ofinputMatrix.A theoretical consequence of how arrays are laid out is that
inputMatrix[i][j]denotes the same address asinputMatrix + M * i + j.¹A practical consequence of this layout is that for efficient code, you should arrange your arrays so that the dimension that varies most often comes last. For example, if you have a pair of nested loops, you will make better use of the cache with
for (i=0; i<N; i++) for (j=0; j<M; j++) ...than with loops nested the other way round. If you need to switch between row access and column access mid-program, it can be beneficial to transpose the matrix (which is better done block by block rather than in columns or in lines).C89 references: §3.5.4.2 (array types), §3.3.2.1 (array subscript expressions)
C99 references: §6.7.5.2 (array types), §6.5.2.1-3 (array subscript expressions).
¹ Proving that this expression is well-defined is left as an exercise for the reader. Whether
inputMatrix[0][M]is a valid way of accessinginputMatrix[1][0]is not so clear, though it would be extremely hard for an implementation to make a difference.