Reputation: 51
i want to pass a matrix to a function in C. If i want to make the dimension of the matrix to be non-constant (eg. let the user insert by keyboard the NxM dimension) i have no problems in this. However when i try to pass this to a function i encounter some problems:
-The number of column MUST be specified in the header of the function(s) who have a matrix as parameter. If i omit this value i get:
error: array type has incomplete element type ‘int[]’ void trasposeMatrix(int M[][],int n,int m) esercizi.c:282:25: note: declaration of ‘M’ as multidimensional array must have bounds for all dimensions except the first
with this function:
void trasposeMatrix(int M[][],int n,int m)
{
int temp=0;
int M2[n][m];
printf("La matrice prima della trasposizione è: \n");
printMatrix(M,3,3);
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
M2[i][j]=M[j][i];
}
}
printf("La matrice dopo la trasposizione è: \n");
printMatrix(M2,3,3);
}
with this call:
trasposeMatrix(M,3,3);
-This value MUST be constant, otherwise if i put a parameter as value in those brackets i get this error:
esercizi.c: At top level: esercizi.c:282:29: error: ‘m’ undeclared here (not in a function) void trasposeMatrix(int M[][m],int n,int m)
with the same call and this code:
void trasposeMatrix(int M[][m],int n,int m)
{
int temp=0;
int M2[n][m];
printf("La matrice prima della trasposizione è: \n");
printMatrix(M,3,3);
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
M2[i][j]=M[j][i];
}
}
printf("La matrice dopo la trasposizione è: \n");
printMatrix(M2,3,3);
}
This can be "avoided" using constants to specify the matrix dimensions. However i don't like this kind of "constraint". Finally what if i would print a matrix via a function: what should i write in the function header if the dimesion is variable?? The function i wrote to print a matrix works well for a 3x3 matrix but what to do for 2x2 matrices and for 3x4. Maybe you got the point
Note: this things do not happen with arrays where i just write a header like:
void printArray(int a[], int dimension){}
and this works. I don't know why. Maybe is a design behaviour of C decided by his inventor, but i hope isn't because is so tediuos
Note 2: :) i'm using linux mint with gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 but with VS for Win10 i even cannot put a variable as dimension of an array :(
I'm so sorry for the very long message, but i hope to get an answer. Thanks for reading
Upvotes: 0
Views: 327
Reputation: 29
"Declaration of ‘M’ as multidimensional array must have bounds for all dimensions except the first"
This tells you that you need to specify a value in the first bracket:
M[]<- can be empty [x]<-cant be empty and has to be constant.
If you don't want to get "constraint" then use malloc and free for allocating dynamic memory at runtime.
Upvotes: 0
Reputation: 753585
Pass the array dimensions before the array in the function call. This feature was added to C99 (and is in C11 and C18, therefore); it is not part of standard C++. That means there are some compilers 'out there' that still don't support the notation.
You have:
void trasposeMatrix(int M[][m],int n,int m)
{
You need:
void trasposeMatrix(int n, int m, int M[n][m])
{
Or perhaps:
void trasposeMatrix(int n, int m, int M[][m])
{
but I think the previous version with both dimensions specified is clearer about the intent.
In the function declarations (in a header, for example), you can use the definition notation (where the extern
is optional and occasionally contentious — there are those who don't like it, and those who do, such as me):
extern void trasposeMatrix(int n, int m, int M[n][m]);
or you can go eccentric and use:
extern void trasposeMatrix(int n, int m, int M[*][*]);
That tells the compiler that the dimensions of the matrix will be determined at runtime, but doesn't indicate where they come from. I prefer the 'copy of the definition' version because the intent is clearer. You can't use the *
notation in the function definition.
If you want to find out 'all about it', you could go read the standard — C11 §6.7.6.2 Array declarators and §6.7.6.2 Function declarators (including prototypes) — but the language is hard to parse.
Upvotes: 1
Reputation: 140960
array type has incomplete element type ‘int[]’
To declare an array the compiler needs to know how big the array elements are.
Imagine int arr[2][];
How big the array elements are? The compiler needs to know how many bytes to "jump" between &arr[0]
and &arr[1]
. How to increment a pointer to arr
?
Imagine int (*arr)[2];
This is a pointer to array of 2 ints. Between &arr[0]
and &arr[1]
are 2 integers: arr[0][0]
and arr[0][1]
exactly. So the compiler knows that &arr[1]
is at position (uintptr_t)(void*)&arr[0] + 2 * sizeof(int)
.
Variable length array declarations (int M[]
) and all array declarations (int M[5]
) "are adjusted" ("are equal to") to a pointer to the types (int *M
) inside function parameter list (see C11 6.7.6.3p7). What that means is that each time you write void func(int a[500*1000*320100])
it's the same as void func(int *a)
.
You can't declare int *(a[]);
a pointer to array to unknown number of elements. Array elements need to be complete type. So the compilers knows how much memory to reserve for them.
error: ‘m’ undeclared here
Imagine a function like this:
int main() {
int m[i];
int i = 5;
}
You will get i undeclared here
. Well, now imagine a function like:
int func(
int m[i],
int i
) {}
You will get the same error, but in function parameter list. It's the same, the variable needs to be declared before it's use.
Upvotes: 0