tags:

views:

313

answers:

5

Hi All,

Consider this code:


#include <stdio.h>
#define N 5
void printMatrix(int (*matrix)[N],int n)
{
   int i,j;
   for(i=0;i<n;i++){
      for(j=0;j<n;j++)
        printf("%d",matrix[i][j]);
     printf("\n");
   }
}
int main()
{
   int R[N][N]={{1,2,3},{4,5,6},{7,8,9}};
   printMatrix(R,3);
}

This works fine as expected.
Now, I thought to write the functions handling 2D-matrices in a separate source file and link them wherever required.
But then I ran into a problem as in the function printMatrix, the size of array of int to which matrix points (i.e N) is required at compile-time. So, my functions would not work in other cases when the size is different.

So,How can I handle this?
Dynamic Arrays are a solution but i want to know if it can be done with static arrays.

+6  A: 

You can't use the built-in 2D array type if both sizes are not known at compile time. A built-in 2D array must have at least one of the two sizes known at compile time.

If both sizes are run-time values, then you have no other choice but to use a "manual" implementation of 2D array, like an array of pointers to arrays, for example. In that case the function declaration might look as follows (two alternative equivalent forms)

void printMatrix(int *const *matrix, int n, int m);
void printMatrix(int *const matrix[], int n, int m);

To access to the array elements you can still use the "traditional" syntax

matrix[i][j]

The array itself would be created as follows (a simple example)

int row0[] = { 1, 2, 3 };
int row1[] = { 4, 5, 6 };

int *matrix[2];
matrix[0] = row0;
matrix[1] = row1;

printMatrix(matrix, 2, 3);

But if you already have a matrix implemented as a built-in 2d array

int matrix[2][3] = { ... };

then just to be able to pass it to the above function you can "convert" it into the above form by using an additional temporary "row pointer" array

int *rows[2];
rows[0] = matrix[0];
rows[1] = matrix[1];

printMatrix(rows, 2, 3);
AndreyT
int rows[2];rows[0] = matrix[0];?????
Brian R. Bondy
thanks.. that was helpful!!
Neeraj
@Brian R. Bondy: It was a typo. I meant `int *rows[2]`. Fixed. Thanks.
AndreyT
+2  A: 

Write yourself a macro:

#define MAT(i,j) matrix[i*n + j];

and declare "matrix" as a simple pointer to an "int".

Steve Emmerson
+2  A: 

Calculate the array index yourself. This will handle an arbitrary two dimensional array, for example:

void printMatrix(int *matrix,int n, int m)
{
   int i,j;
   for(i=0;i<n;i++){
    for(j=0;j<m;j++)
     printf("%d",matrix[m * i + j]);
   printf("\n");
   }
}
Richard Pennington
A: 

Although the syntax is not exactly the same, but this also happens to work a bit:


#include <stdio.h>
#define N 5
void printMatrix(int* row,int n,int sz)
{
   int i,j;
   int *currRow;
   for(i=0;i<n;i++){
      currRow = row+i*sz;
      for(j=0;j<n;j++)
        printf("%d",currRow[j]);
     printf("\n");
   }
}
int main()
{
   int R[N][N]={{1,2,3},{4,5,6},{7,8,9}};
   printMatrix(R[0],3,sizeof(R[0])/sizeof(int));
}


Neeraj
+1  A: 

Don't try to pass it as a 2-D array; pass a pointer to the first element, then compute offsets manually:

void printMatrix(int *a, size_t m, size_t n)
{
  size_t i,j;
  for (i = 0; i < m; i++)
  {
    for (j = 0; j < n; j++)
    {
      printf("a[%lu][%lu] = %d\n",
       (unsigned long) i, 
       (unsigned long) j, 
       a[i*n+j]); // treat a as 1-d array, compute offset manually
    }
  }
}

int main(void)
{
  int arr[5][4];
  ...
  printMatrix(&arr[0][0], 5, 4);
  ...
}

Granted, this will only work for contiguously allocated arrays.

John Bode