samuele55598
samuele55598

Reputation: 51

C-Pass a matrix to function without non-constant column value

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

Answers (3)

Tim Weissenfels
Tim Weissenfels

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

Jonathan Leffler
Jonathan Leffler

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

KamilCuk
KamilCuk

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

Related Questions