How to pass two-dimensional array as an argument?

前端 未结 6 881
萌比男神i
萌比男神i 2020-12-14 23:47

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 o         


        
相关标签:
6条回答
  • 2020-12-15 00:18

    You're lucky, then because:

    for(int j=0;j<m;j++)
        A[i][j]=0.0;
    

    should probably be:

    for(int j=0;j<**n**;j++)
        A[i][j]=0.0;
    
    0 讨论(0)
  • 2020-12-15 00:21

    You need to specify all but the first dimension, e.g.

    void Matrx::readMatrx(double a[][50])
    

    From this you should be able to see that you have a fundamental problem with the way you have implemented your class, but at least you should now be able to get the code to compile.

    0 讨论(0)
  • 2020-12-15 00:22

    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.

    0 讨论(0)
  • 2020-12-15 00:23

    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.

    0 讨论(0)
  • 2020-12-15 00:32

    You can to specify all dimensions or only last dimension to pass an array:

    void Matrx::readMatrx(double a[][50])
    {
     for(int i=0;i< m;i++)
      {
       for(int j=0;j< n;j++)
        A[i][j]=a[i][j];
      }
    }
    
    0 讨论(0)
  • 2020-12-15 00:42

    Thanks to all of you people...you were really helping...I have found myself a new definition of the class and the function definition for the matrix that fitted my need. I need you r comment on it...Below is the example of the class declaration..

    #include<iostream>
    #include"stdafx.h"
    using namespace std;  
    const int M=100; const int N=100;  
    class Matrix  
    {  
        double A[M][N];  
        int m,n;  
    public:  
        Matrix(void);  
        Matrix(int a, int b)  
        {  
            m=a;  
            n=b;  
            for(int i=0;i<m;i++)  
            {  
                for(int j=0;j<m;j++)  
                    A[i][j]=0.0;  
            }  
        }  
        Matrix operator +(Matrix b);  
        Matrix operator -(Matrix b);  
        Matrix operator *(Matrix b);  
        void TransPose(Matrix b);  
        CString printMatrix();  
        void readMatrix(double*);  
    };
    

    and then the function implementation

    #include "stdafx.h"
    #include "Matrix.h"
    
    Matrix::Matrix(void)  
    {  
    }  
    
    Matrix Matrix::operator *(Matrix b)  
    {  
     Matrix c(m,m);  
     if(n!=b.m)  
     {  
        HWND hndOwner(0);   
        MessageBoxW(hndOwner,L"Multiplication not possible row and column does not match",L"Error",NULL);  
        Matrix errMat(1,0);  
        double er[1][1]={0}; errMat.readMatrix((double *)er);  
        return errMat;  
     }  
    for(int i=0;i< m;i++)  
    {  
    for(int k=0;k< m;k++)  
    {  
    c.A[i][k]=0;  
    for(int j=0;j< n;j++)  
    {  
    c.A[i][k] = c.A[i][k]+(A[i][j] * b.A[j][k]) ;  
    }  
    }  
    }  
    return c;  
    }  
    Matrix Matrix::operator +(Matrix b)  
    {  
        Matrix c(m,n);  
        if((n!=b.n)||(m!=b.m))  
     {  
        HWND hndOwner(0);   
        MessageBoxW(hndOwner,L"Addition not possible row and column does not match",L"Error",NULL);  
        Matrix errMat(1,0);  
        double er[1][1]={0}; errMat.readMatrix((double *)er);  
        return errMat;  
     }  
        for(int i=0;i<m;i++)  
            {  
                for(int j=0;j< n;j++)  
                    {  
                        c.A[i][j]=0.0;  
                    }  
            }  
            for(int i=0;i< m;i++)  
            {  
                for(int j=0;j< n;j++)  
                    {  
                        c.A[i][j]=A[i][j]+b.A[i][j];  
                    }  
            }  
    return c;  
    }    
    CString Matrix::printMatrix()  
    {  
        CString strB(" "),strDisp;  
        for(int iRow=0;iRow<m;iRow++)  
        {  
            for(int iColumn=0;iColumn<n;iColumn++)  
            {  
                strB.Format(L"%lf ",A[iRow][iColumn]);  
                strDisp+=strB;  
            }  
                strDisp+="\r\n";  
        }  
            return strDisp;  
    }  
    void Matrix::readMatrix(double *ptrarr)  
    {  
        for(int i=0;i< m;i++)  
            {  
                for(int j=0;j< n;j++)  
                    A[i][j]=*(ptrarr+i*n+j);  
            }  
    }  
    void Matrix::TransPose(Matrix b)  
    {  
        for(int i=0;i<b.n;i++)  
        {  
            for(int j=0;j<b.m;j++)  
                A[i][j]=b.A[j][i];  
        }  
    }   
    

    The simple codes in the above are working well till now...if you have any suggestion for the improvement please suggest..

    0 讨论(0)
提交回复
热议问题