Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass two-dimensional array as an argument?

My Matrx class is defined as

class Matrx
{
 double A[50][50];
 int m,n;
public:
 Matrx(void);
 Matrx(int a, int b)
 {
  m=a;
  n=b;
 }
 Matrx operator +(Matrx b);
 Matrx Transpose(Matrx b);
 Matrx operator *(Matrx b);
 CString printMatrx();
 void readMatrx(double a[][]);
 Matrx TransposeMat(Matrx b);
};

void Matrx::readMatrx(double a[][])
{
 for(int i=0;i< m;i++)
  {
   for(int j=0;j< n;j++)
    A[i][j]=a[i][j];
  }
}

The intellisense gives error like the below

1 IntelliSense: an array may not have elements of this type d:\bmadaptive_dd_v1.02\matrx.h 17 27 TestServer

Why?

How to pass a two dimensional array as argument of the function?

like image 246
user543265 Avatar asked Jan 26 '11 08:01

user543265


People also ask

Can you pass a 2D array into a function?

Notice the parameter int num[2][2] in the function prototype and function definition: // function prototype void displayNumbers(int num[2][2]); This signifies that the function takes a two-dimensional array as an argument. We can also pass arrays with more than 2 dimensions as a function argument.

How do I pass a 2D dynamic array to a function in CPP?

int **board; board = new int*[boardsize]; for (int i = 0; i < boardsize; i++) board[i] = new int[size]; You need to allocate the second depth of array. Save this answer.

How is a 2 dimensional array initialised?

Like the one-dimensional arrays, two-dimensional arrays may be initialized by following their declaration with a list of initial values enclosed in braces. Ex: int a[2][3]={0,0,0,1,1,1}; initializes the elements of the first row to zero and the second row to one. The initialization is done row by row.


2 Answers

The problem is that when passing multidimensional arrays as parameters in C++, you must specify the dimension of the outermost array. For example:

void ThisIsIllegal(int arr[][]); // Wrong!
void ThisIsAlsoIllegal(int arr[10][]); // Also wrong
void ThisIsLegal(int arr[][10]); // Okay

If you want to be able to have a function that takes in an array of any size, you can use templates:

template <size_t N, size_t M>
void ThisIsAlsoLegal(int (&arr)[M][N]);

This last version accepts any multidimensional array of the right type, and is probably what you're looking for.

like image 172
templatetypedef Avatar answered Nov 07 '22 13:11

templatetypedef


You need to properly learn about arrays and pointers. This includes the lesson "huh! They are not as useful as I thought they were". After you've gotten familiar with how arrays and pointers work exactly you should rethink your design.

For example, in my opinion, the following design has lots of advantages:

#ifndef MATRIX_HPP_INCLUDED
#define MATRIX_HPP_INCLUDED

#include <vector>
#include <algorithm>

class matrix
{
public:
    typedef std::vector<double>::size_type st;
    matrix() : rows_(0), cols_(0) {}
    matrix(int r, int c) : rows_(r), cols_(c), coeffs_(st(r)*c,0.0) {}
    void reset(int r, int c)
    { rows_=r; cols_=c; coeffs_.clear(); coeffs_.resize(st(r)*c,0.0); }
    int rows() const {return rows_;}
    int cols() const {return cols_;}
    double const& operator()(int i, int j) const {return coeffs_[indexof(i,j)];}
    double      & operator()(int i, int j)       {return coeffs_[indexof(i,j)];}
    double const* operator[](int i) const {return &coeffs_[indexof(i,0)];}
    double      * operator[](int i)       {return &coeffs_[indexof(i,0)];}
    void swap(matrix& that)
    {
      std::swap(this->rows_,that.rows_);
      std::swap(this->cols_,that.cols_);
      this->coeffs_.swap(that.coeffs_));
    }
private:
    int rows_, cols_;
    std::vector<double> coeffs_;
    st indexof(int i, int j) const {return st(i)*cols+j;} // row major storage
};

inline void swap(matrix& a, matrix& b) {a.swap(b);}

matrix& operator+=(matrix& lhs, matrix const& rhs);
matrix operator+(matrix const& lhs, matrix const& rhs);
matrix operator*(matrix const& lhs, matrix const& rhs);
inline matrix& operator*=(matrix& lhs, matrix const& rhs)
{ matrix tmp = lhs * rhs; swap(tmp,lhs); return lhs; }
...

#endif

This way you won't waste any space for small matrices, and you can support large matrices. Also, the use of std::vector instead of a pointer member which points to dynamically allocated memory removes the need to define your own copy constructor, assignment operator and destructor.

Of course, you could use boost::multi_array as a matrix replacement but using a custom matrix class allows you to declare overloaded operators in your own namespace which is desirable due to ADL (argument dependent lookup).

You might think that this doesn't really answer your question. In that case, let me stress that I think you don't fully understand how arrays and pointers work / behave. This is something you should look up in a decent C++ book. One could write many pages about this topic. You can't expect to see a short answer explaining all the quirks.

Check out the Definite C++ Book Guide thread.

like image 23
sellibitze Avatar answered Nov 07 '22 14:11

sellibitze