如何将二维数组作为参数传递?

use*_*265 9 c++ arrays multidimensional-array

我的Matrx班级被定义为

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];
  }
}
Run Code Online (Sandbox Code Playgroud)

intellisense给出如下错误

1 IntelliSense:阵列可能没有此类型的元素d:\ bmadaptive_dd_v1.02\matrx.h 17 27 TestServer

为什么?

如何传递二维数组作为函数的参数?

tem*_*def 25

问题是当在C++中将多维数组作为参数传递时,必须指定最外层数组的维度.例如:

void ThisIsIllegal(int arr[][]); // Wrong!
void ThisIsAlsoIllegal(int arr[10][]); // Also wrong
void ThisIsLegal(int arr[][10]); // Okay
Run Code Online (Sandbox Code Playgroud)

如果您希望能够使用任何大小的数组,您可以使用模板:

template <size_t N, size_t M>
void ThisIsAlsoLegal(int (&arr)[M][N]);
Run Code Online (Sandbox Code Playgroud)

最后一个版本接受任何正确类型的多维数组,可能正是您正在寻找的.

  • class Matrx {---------------------- template <size_t N,size_t M> void readMatrx(double(&a)[M] [N]); Matrx TransposeMat(Matrx b); }; 我改变了我的类,我的函数就像模板<size_t N,size_t M> void Matrx :: readMatrx(double a [M] [N]){for(int i = 0; i <m; i ++){for (int j = 0; j <n; j ++)A [i] [j] = a [i] [j]; 仍然编译器给出错误错误2错误C2244:'Matrx :: readMatrx':无法将函数定义与现有声明匹配d:\ bmadaptive_dd_v1.02\matrx.cpp 67 1此行上的TestServer Wtest.readMatrx(W) ; (2认同)
  • "......你必须指定除最内层维度以外的所有维度"以推广到所有数组(包括单个维度),否则ThisIsAlsoLegal也是我建议的. (2认同)

sel*_*tze 4

您需要正确了解数组和指针。这包括“哈!它们并不像我想象的那么有用”这一教训。在熟悉了数组和指针的确切工作原理后,您应该重新考虑您的设计。

例如,在我看来,以下设计有很多优点:

#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
Run Code Online (Sandbox Code Playgroud)

这样你就不会为小矩阵浪费任何空间,并且可以支持大矩阵。此外,使用 std::vector 而不是指向动态分配内存的指针成员,无需定义自己的复制构造函数、赋值运算符和析构函数。

当然,您可以使用 boost::multi_array 作为矩阵替换,但使用自定义矩阵类允许您在自己的命名空间中声明重载运算符,这由于 ADL(参数相关查找)而非常理想。

您可能认为这并不能真正回答您的问题。在这种情况下,让我强调一下,我认为您没有完全理解数组和指针的工作/行为方式。这是你应该在一本像样的 C++ 书籍中查找的内容。关于这一主题,人们可以写很多页。您不能指望看到一个简短的答案来解释所有的怪癖。

查看Definite C++ 书籍指南线程。