7

I'm Java developer, not a C programmer. I'm trying to invoke some function that receives a 2D array, tried like:

#include <stdio.h>
int foo(int mat[][N])
{ 
  printf("%d",N); /*  <--- here error */

}

int main()
{
    int a[5][5] =
    {
        {1, 2, 3, 4,5},    
        {1, 5, 5, 5,2},    
        {1, 4, 30,4,2},
        {1, 2, 2,2, 2},
        {1,1, 1,1,  2 } 
    };

    foo(a);
    return 0;
}

But the compiler says:

'N' undeclared (first use in this function)

I must have the signature: int foo(int mat[][N])

How should I pass the 2D array then?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Devy
  • 703
  • 6
  • 17
  • 3
    You should define `N`. – Eugene Sh. Dec 10 '18 at 18:47
  • `'N' undeclared`. Declare `N`. – KamilCuk Dec 10 '18 at 18:48
  • But it doesn't know that `a` is `5X5` matrice ? @EugeneSh. – Devy Dec 10 '18 at 18:48
  • @Malwarey How would it? Put yourself in the place of the compiler. you're generating code for your source file. After the preprocessor finishes sucking in all the stuff from the `#include`s and performed macro expansions, etc, you're on to actually compiling source and the first thing you see here is `int foo(int mat[][N])`. Now, how do you know what `N` is *at that time* ? It isn't inferred nor deduced by the compiler. That isn't how C works. – WhozCraig Dec 10 '18 at 18:51
  • You should also use `N` in the array definition, not `5`. – Weather Vane Dec 10 '18 at 18:57
  • 3
    C arrays are contiguous blocks of memory. They do not "remember" their size. – DYZ Dec 10 '18 at 18:57
  • When you pass an array to a function, all dimensions must match the function argument except the outermost dimension. – Weather Vane Dec 10 '18 at 18:58
  • If you "must" have the signature `int foo(int mat[][N])`, then you have to define `N`, like in `#define N 5`, before using it. In `main` you could declare `int a[N][N] = {...`. If you can change the signature, follow the suggestions at the link provided in the comment by Andrew Fan. – Bob__ Dec 10 '18 at 19:07
  • Post your assignment verbatim, it's rather difficult to guess what it says exactly. – n. m. could be an AI Dec 10 '18 at 19:19
  • Note that if the function signature cannot be changed, then you must define an integer constant for `N` (`#define N 5` or `enum { N = 5 };`) before the function is defined. The first duplicate shows how to deal with variable size arrays, which will be more useful in the long run, while the second deals with 'fixed size arrays' (where the second dimension is fixed at compile time — the first dimension is still allowed to vary). – Jonathan Leffler Jan 23 '19 at 00:24

2 Answers2

1

You can use macros to define constant numbers, i.e. #define N 5. At compile time each appearance of the defined macro name will be replaced with the given value. In our case each N would be replaced with 5. But this would not solve your problem, because it would print 5 every time, even if you change the dimensions of your array.

Pass the dimensions of the array as parameters.

You can pass the 2D array as a pointer.

I created a printing function, with what I can show you accessing the elements from the array. So the function's prototype would look like:

void print2DMatrix(int *matrix2D, const int rowLength, const int columnLength);

where matrix2D is a pointer, there will be passed the address of the array. The other two parameters tell us the dimensions of the array.

We can access the elements in a selected row and in a selected column with matrix2D[selectedRow * maxRowLength + selectedColumn].

When you call the function, you can pass the name of the array, like print2DMatrix(*myMatrix, myRowLength, myColumnLength);, of course you shall declare and initialize it before using. print2DMatrix(myMatrix, myRowLength, myColumnLength); would cause warning, because the passed argument and the waited one have different types, but it will run correctly. The passed one is a double pointer, when the waited one is a single pointer. Because of that you have to use print2DMatrix(*myMatrix, myRowLength, myColumnLength);, where *myMatrix will point to the first row of our array.

I would like to mention that myMatrix and *myMatrix point to the same address, the difference is: myMatrix is looked as a double pointer to an integer, when *myMatrix is looked as a pointer to an integer. Run printf("%d %d %d", myMatrix, *myMatrix, **myMatrix); to see the result. **myMatrix will point to the first element of the first row, what is 11. See the entire code below...

#include <stdio.h>

#define ROW_LENGTH      5
#define COLUMN_LENGTH   5

void print2DMatrix(int *matrix2D, const int rowLength, const int columnLength)
{
    int i;
    for (i = 0; i < rowLength; i++)
    {
        int j;
        for (j = 0; j < columnLength; j++)
        {
            printf("%d ", matrix2D[i * rowLength + j]);
        }
        printf("\n");
    }
}

int main(void)
{
    const int myRowLength = ROW_LENGTH;
    const int myColumnLength = COLUMN_LENGTH;
    int myMatrix[ROW_LENGTH][COLUMN_LENGTH] =
    {
        {11, 12, 13, 14, 15},
        {21, 22, 23, 24, 25},
        {31, 32, 33, 34, 35},
        {41, 42, 43, 44, 45},
        {51, 52, 53, 54, 55}
    };

    print2DMatrix(*myMatrix, myRowLength, myColumnLength);

    return 0;
}
Community
  • 1
  • 1
Norbert Incze
  • 351
  • 3
  • 11
  • 1
    See also [`static const` vs `#define` vs `enum](https://stackoverflow.com/questions/1674032/static-const-vs-define-vs-enum). – Jonathan Leffler Jan 23 '19 at 00:11
  • Thank you so much for your answer, @Norbert Incze. Could you please explain why are you accessing each element with `matrix2D[selectedRow * maxRowLength + selectedColumn]` ? – F. Zer Oct 12 '21 at 17:12
0

You are trying to print a non existent value. N is not a declared variable.

The function foo is receiving a pointer. Unlike java, C deals with pointers, not objects, it does not have any information about what it received, except that it is a pointer that contains addresses to ints. Therefore, the function does not know (or care) about your array being of size N (regardless of you mentioning N) .

When you call printf there's nothing in memory called N, which explains the error.

You could always send a second argument which is an int specifying the size and print that one.

void foo(int[][] mat, int matSize){
  printf("%d\n",matSize);
}

Notice how I used int[][] this is to simplify and illustrate the fact that is just a pointer.

LeedMx
  • 424
  • 4
  • 19
  • Note that `void foo(int [][] mat, int matSize)` is not C. The subscripts would appear after `mat`, and the second one, at least, needs a dimension specified. – Jonathan Leffler Jan 23 '19 at 00:15