My Matrx
class is defined as
我的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];
}
}
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
1 IntelliSense:一个数组可能没有d类型的元素:\bmadaptive_dd_v1.02\matrx。h 17 27 TestServer
Why?
为什么?
How to pass a two dimensional array as argument of the function?
如何传递一个二维数组作为函数的参数?
6 个解决方案
#1
4
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.
这样你就不会浪费任何空间给小矩阵了,你可以支持大矩阵。此外,使用std::vector而不是指向动态分配内存的指针成员,就不需要定义自己的复制构造函数、赋值操作符和析构函数。
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).
当然,您可以使用boost::multi_array作为矩阵替换,但是使用自定义矩阵类允许您在自己的名称空间中声明重载的操作符,这是由于ADL(参数依赖的查找)所需要的。
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.
你可能认为这并不能真正回答你的问题。在这种情况下,让我强调一下,我认为您不完全理解数组和指针的工作/行为。这是你应该在一本像样的c++书中查找的东西。一个人可以写很多关于这个话题的文章。你不可能期望看到一个简短的回答来解释所有的怪癖。
Check out the Definite C++ Book Guide thread.
查看明确的c++图书指南线程。
#2
25
The problem is that when passing multidimensional arrays as parameters in C++, you must specify the dimension of the outermost array. For example:
问题是,在c++中将多维数组作为参数传递时,必须指定最外层数组的维数。例如:
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.
最后一个版本接受任何正确类型的多维数组,这可能是您正在寻找的。
#3
1
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.
从这里,您应该可以看到实现类的方式有一个基本问题,但至少现在应该能够编译代码。
#4
0
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];
}
}
#5
0
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..
以上简单的代码到目前为止运行良好……如果你有什么改进的建议,请建议。
#6
-1
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;
#1
4
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.
这样你就不会浪费任何空间给小矩阵了,你可以支持大矩阵。此外,使用std::vector而不是指向动态分配内存的指针成员,就不需要定义自己的复制构造函数、赋值操作符和析构函数。
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).
当然,您可以使用boost::multi_array作为矩阵替换,但是使用自定义矩阵类允许您在自己的名称空间中声明重载的操作符,这是由于ADL(参数依赖的查找)所需要的。
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.
你可能认为这并不能真正回答你的问题。在这种情况下,让我强调一下,我认为您不完全理解数组和指针的工作/行为。这是你应该在一本像样的c++书中查找的东西。一个人可以写很多关于这个话题的文章。你不可能期望看到一个简短的回答来解释所有的怪癖。
Check out the Definite C++ Book Guide thread.
查看明确的c++图书指南线程。
#2
25
The problem is that when passing multidimensional arrays as parameters in C++, you must specify the dimension of the outermost array. For example:
问题是,在c++中将多维数组作为参数传递时,必须指定最外层数组的维数。例如:
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.
最后一个版本接受任何正确类型的多维数组,这可能是您正在寻找的。
#3
1
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.
从这里,您应该可以看到实现类的方式有一个基本问题,但至少现在应该能够编译代码。
#4
0
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];
}
}
#5
0
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..
以上简单的代码到目前为止运行良好……如果你有什么改进的建议,请建议。
#6
-1
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;