A_Student
A_Student

Reputation: 3

C: All possible ways to pass a matrix to function and some info about argc and argv

Since days I got stucked in some multiple compiling error, at the bottom, my biggest error is one, and you can see in the following code.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void generateMatrix(int rows, int cols, int matr[][]);
void show(int rows, int cols, int matr[][]);
// void analize(int matr[rows][cols], int rows, int cols);

int main(int argc, char* argv[])
{
    srand(time(NULL));
    if(argc < 3)
    {
        printf("Not enough inputed arguments, you have to insert only two number, one for rows the last for cols\n");
        return 1;
    }
    else
    {
        int rows = atoi(argv[1]), cols = atoi(argv[2]);
        int mat[rows][cols];
        generateMatrix(rows, cols, mat);
        show(rows, cols, mat);
        // analize(mat, rows, cols);
        
        return 0;
    }
}

void generateMatrix(int rows, int cols, int matr[][])
{
    for(int i=0; i<rows; i++)
        for(int j=0; j<cols; j++)
            matr[i][j] = rand() % 20;
}

void show(int rows, int cols, int matr[][])
{
    for(int i=0; i<rows; i++)
    {
        for(int j=0; j<cols; j++)
            printf("%5d", matr[i][j]);
        printf("\n");
    }
}

Here the result of compilation:

t.c:5:45: error: array type has incomplete element type ‘int[]’
    5 | void generateMatrix(int rows, int cols, int matr[][]);
      |                                             ^~~~
t.c:5:45: note: declaration of ‘matr’ as multidimensional array must have bounds for all dimensions except the first
t.c:6:35: error: array type has incomplete element type ‘int[]’
    6 | void show(int rows, int cols, int matr[][]);
      |                                   ^~~~
t.c:6:35: note: declaration of ‘matr’ as multidimensional array must have bounds for all dimensions except the first
t.c: In function ‘main’:
t.c:21:36: error: type of formal parameter 3 is incomplete
   21 |         generateMatrix(rows, cols, mat);
      |                                    ^~~
t.c:22:26: error: type of formal parameter 3 is incomplete
   22 |         show(rows, cols, mat);
      |                          ^~~
t.c: At top level:
t.c:29:45: error: array type has incomplete element type ‘int[]’
   29 | void generateMatrix(int rows, int cols, int matr[][])
      |                                             ^~~~
t.c:29:45: note: declaration of ‘matr’ as multidimensional array must have bounds for all dimensions except the first
t.c:36:35: error: array type has incomplete element type ‘int[]’
   36 | void show(int rows, int cols, int matr[][])
      |                                   ^~~~
t.c:36:35: note: declaration of ‘matr’ as multidimensional array must have bounds for all dimensions except the first

Ok now the questions:

  1. What is necessary to fix errors?
  2. Is possible to improve something in this code, without changing to much?? (optional)
  3. In this case matrix will work as pointers? (Work saving data and passing to functions correctly?)

Thanks of time taken and future answer.

Upvotes: 0

Views: 201

Answers (2)

Andrew Henle
Andrew Henle

Reputation: 1

You left out the easiest way to allocate or pass a matrix of variable dimensions - using a VLA (variable-length array):

// return a pointer to a VLA
void *allocateArray( size_t x, size_t y )
{
    int (*array)[ x ][ y ] = malloc( sizeof( *array ) );

    return( array );
}

Note that the return type is void *, so there's no type safety.

This will allocate the array in a more type-safe manner

void allocateArray( size_t x, size_t y, int ( **array )[x][y] )
{
    *array = malloc( sizeof( **array ) );

    return( array );
}

And you can use this form to process a matrix:

void printMatrix( size_t x, size_t y, int array[x][y] )
{
    for ( size_t ii = 0; ii < x; ii++ )
    {
        char *separator = "";
        for ( size_t jj = 0; jj < y; jj++ )
        {
            printf( "%s%d", sep, array[ ii ][ jj ] );
            separator = ", ";
        }
        printf( "\n" );
    }
}

VLAs do require a C99-compliant compiler. In C11, VLAs were made optional, but a conforming C11 compiler that does not support VLAs must define __STDC_NO_VLA__.

Upvotes: 1

Joshua
Joshua

Reputation: 43227

The compiler can't possible handle int matr[][] as a function argument.

The easiest way to fix this is to pass it as int *matr. You de-reference it as follows: matr[i * cols + j]. Due to row-major ordering this is accessing it in the correct order. To supress a compiler warning, you will need to pass it by typing &matr[0][0]. Most programmers will not depend on the defined ordering of multi-dimensional arrays and go ahead and declare it as a single dimension.

const is how you say something can't be written to via that reference to it. So yes, you can declare your variables const. It doesn't break anything. Note that you have to assign to a const when you define it, which is exactly what you want to do anyway.

Upvotes: 0

Related Questions