18

I want to make class library, a function which its parameter is a matrix of unknown size, and the user will create his own matrix with his own size and pass it to this function to do some operations on his matrix like this, will be the function

calculateDeterminantOfTheMatrix( int matrix[][])
{
   some Operations to do on matrix 
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115

6 Answers6

23

Multi-dimensional arrays are not very well supported by the built-in components of C and C++. You can pass an N-dimension array only when you know N-1 dimensions at compile time:

calculateDeterminantOfTheMatrix( int matrix[][123])

However, the standard library supplies std::vector container, that works very well for multi-dimension arrays: in your case, passing vector<vector<int> > &matrix would be the proper way of dealing with the task in C++.

int calculateDeterminantOfTheMatrix(vector<vector<int> > &matrix) {
    int res = 0;
    for (int i = 0 ; i != matrix.size() ; i++)
        for(int j = 0 ; j != matrix[i].size() ; j++)
            res += matrix[i][j];
    return res;
}

As an added bonus, you wouldn't need to pass dimensions of the matrix to the function: matrix.size() represents the first dimension, and matrix[0].size() represents the second dimension.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • in case i declare it `calculateDeterminantOfTheMatrix(vector > &matrix)` will i be able to loop on it like this `for(matrix[rowNumber][columnNumber]` –  Apr 15 '12 at 17:32
  • @AhmedZainElDein I added an example of looping over the elements of the matrix in case when you pass in a `vector >`. – Sergey Kalinichenko Apr 15 '12 at 17:39
  • @AhmedZainElDein You can make it work, but it is much harder: you need to allocate it differently, pass sizes in separate arguments, and free everything once you're done. – Sergey Kalinichenko Apr 15 '12 at 18:01
  • 1
    @AhmedZainElDein Here is a [link](http://stackoverflow.com/a/936702/335858) to an answer that shows the pointer to pointer technique. – Sergey Kalinichenko Apr 16 '12 at 02:39
  • Note that for a vector of vectors, each access costs 3 pointer dereferences instead of the one you get using a two-dimensional array (with dimensions known at runtime of course). You dereference the outer vector to find a pointer to the vector's memory, which you dereference to access the inner vector, which then gets dereferenced to find the actual integers you are looking for. Traditionally it only costs a multiplication and a single dereference. – mdenton8 Jul 29 '15 at 05:14
7

C solution:

In C you can't omit array size (except leftmost) when passing as function parameter.

You can write: int a[]

but can't: int a[][]

just for example: int a[][20]

This constraint is here, because compiler needs to determine proper offsets for accessing array elements. However, you can make it this way:

void print_arbitrary_2D_array(void *arr, int y, int x)
{
    /* cast to 2D array type */
    double (*p_arr)[y][x] = (double (*)[y][x]) arr;

    int i, j;

    for (i = 0; i < y; ++i) {
        for (j = 0; j < x; ++j)
            printf(" %lf", (*p_arr)[i][j]);
        putchar('\n');
    }
}

double arr_1[4][3] = {
    { 3.3, 5.8, 2.3 },
    { 9.1, 3.2, 6.1 },
    { 1.2, 7.9, 9.4 },
    { 0.2, 9.5, 2.4 }
};
double arr_2[2][5] = {
    { 3.6, 1.4, 6.7, 0.1, 4.2 },
    { 8.4, 2.3, 5.9, 1.4, 8.3 }
};

print_arbitrary_2D_array(arr_1, 4, 3);
putchar('\n');
print_arbitrary_2D_array(arr_2, 2, 5);
Julius
  • 71
  • 1
  • 1
1

There are multiple approaches you could take.

  1. C way of doing things -> Pass in a int** but be extremely cautious here. This is not quite a 2D array. You will have to correctly allocate memory to this pointer, or, alternatively, you need to know the size at compile time. (For instance staticly allocating an array of size M * N and then disallowing anything bigger). In order to dynamically allocate the memory, you need to know the number of rows and columns.

  2. C++ way -> #include <vector> after which you can simply use vector<vector<int> > &matrix (Careful about the space after the <int> unless you're using c++11 compiler.), which will allocate a vector of int vectors which is basically a 2d array. The memory management will be taken care of for you in this case.

ScarletAmaranth
  • 5,065
  • 2
  • 23
  • 34
  • The C way of doing things also gets complicated when you consider that the 2D array could be stored row-wise or column-wise. – mdenton8 Jul 29 '15 at 05:17
1

I would write a simple class wrapper for the matrix with column and row defined.

template <typename T>
class Mat {
  std::size_t _row;
  std::size_t _col;

  T *_mat_elem;
public:
  Mat(std::size_t r, std::size_t c)
   :  _row(r), _col(c), _mat_elem(new T[r*c] {}
  ~Mat() {/* remember to do delete [] here */}

  // element access, for example
  T& at(std::size_t r, std::size_t c)
  {
    return *(_mat_elem+r*_col+c);
  }
};

But actually you are re-inventing the wheels. There are good libraries for matrix handling out there.

user2k5
  • 827
  • 1
  • 7
  • 9
0

use this method declare an array of pointers ex: int *a[n]; Then allocate memory for them using a for loop ex:

for( int i=0 ; i<n ; i++ )
        a[i] = new int[n];

Now pass the argument like normal array. ex: print_array(a,n); And print_array function looks like

print_array(int **a,int n)//the prototype for the print_array
{
 //access the array using index such as
std:: cout<<a[1][1]<<endl;
}

The above case is for the array of nxn incase mxn is required then allocate the memory like

for( int i=0 ; i<m ; i++ )
        a[i] = new int[n];

then pass the both m,n and to the function and access the array in the for loop.

Pranu Pranav
  • 353
  • 3
  • 8
0

The Best way to use 2D array in the function that I have found so far is to use Mapping Function. As in the example below , I have use the mapping function to print 2D array

void Print2D(int x[],int ROWS,int COLS)
{
    for(int i=0;i<ROWS;i++)
{
    for(int j=0;j<COLS;j++)
    cout << x[i*COLS+j] << ' ';
    cout << endl;

}
}

Here it is how to use it in main

int main(){

    int x[3][3];
    Print2D(&x[0],3,3);

}

Here &x[0] is the starting address of the First Row of 2D array or more precisely Starting address of 2D array