什么OP正在尝试是如此令人讨厌的难以得到正确的做法,并且与成本相比,拉动它的好处是微不足道的......好吧,我会引用经典。
The only winning move is not to play.
-Joshua,战争游戏
你不能安全地通过在C++中动态分配二维数组到一个函数,因为你总是要在编译时知道至少有一个尺寸。
我可以指向Passing a 2D array to a C++ function,因为这看起来像一个很好的重复。我不会因为它指的是静态分配的数组。
你可以玩愚蠢的铸造游戏来强制数组进入函数,然后将其重新投射到里面。我不会解释如何做到这一点,因为它是史诗级的愚蠢,应该是一个射击罪。
您可以将指针传递给指针int **
,但构造和销毁逻辑是一个奇怪的集合new
和循环。此外,最终结果会散布RAM周围的已分配内存,削弱处理器在预测和缓存方面的尝试。在现代处理器上,如果你无法预测和缓存,你会抛弃CPU的大部分性能。
你想要做的是保持一维。一维数组很容易通过。索引算法非常简单,易于预测。这都是一个内存块,所以缓存命中更有可能不会。
制作一维数组很简单:不要。改为使用std::vector
。
std::vector<int> arr(rows*columns);
如果您必须因为赋值规范说“无向量!”那么你卡住了。
int * arr = new int[rows*columns];
注意我使用rows
和columns
不M
和N
。当遇到M
和N
这是哪个?谁知道,谁在乎,为什么这样对自己首先呢?给你的变量提供一个好的描述性的名字,并且在稍后调试时能够节省读取代码的时间。
使用的胆与阵列和矢量相同:
int test = arr[row * columns + column];
将在[row][column]
恢复在二维空间中的元件。我不应该解释这些变量的含义。死亡至M
和N
。
定义函数是:
void function (std::vector<int> & arr, size_t rows, size_t columns)
或(呸)
void function (int * arr, size_t rows, size_t columns)
注意rows
和columns
是size_t
类型。 size_t
是无符号数(负数组大小不是你想要的,所以为什么允许它?),并且它保证足够大以保存可以使用的最大可能数组索引。换句话说,它比int
更合适。但为什么到处通过rows
和columns
?在这一点上做的聪明的事情是围绕数组及其控制变量进行封装,然后使用几个函数来使事情更易于使用。
template<class TYPE>
class Matrix
{
private:
size_t rows, columns;
std::vector<TYPE> matrix;
public:
// no default constructor. Matrix is BORN ready.
Matrix(size_t numrows, size_t numcols):
rows(numrows), columns(numcols), matrix(rows * columns)
{
}
// vector handles the Rule of Three for you. Don't need copy and move constructors
// a destructor or assignment and move operators
// element accessor function
TYPE & operator()(size_t row, size_t column)
{
// check bounds here
return matrix[row * columns + column];
}
// constant element accessor function
TYPE operator()(size_t row, size_t column) const
{
// check bounds here
return matrix[row * columns + column];
}
// stupid little getter functions in case you need to know how big the matrix is
size_t getRows() const
{
return rows;
}
size_t getColumns() const
{
return columns;
}
// and a handy-dandy stream output function
friend std::ostream & operator<<(std::ostream & out, const Matrix & in)
{
for (int i = 0; i < in.getRows(); i++)
{
for (int j = 0; j < in.getColumns(); j++)
{
out << in(i,j) << ' ';
}
out << '\n';
}
return out;
}
};
粗糙的阵列版本将不得不看起来像只是为了显示允许向量来做它的工作的好处。未经测试。可能包含咯咯声。重点在于更多的代码和更多的错误空间。
template<class TYPE>
class ArrayMatrix
{
private:
size_t rows, columns;
TYPE * matrix;
public:
ArrayMatrix(size_t numrows, size_t numcols):
rows(numrows), columns(numcols), matrix(new TYPE[rows * columns])
{
}
// Array version needs the copy and move constructors to deal with that damn pointer
ArrayMatrix(const ArrayMatrix & source):
rows(source.rows), columns(source.columns), matrix(new TYPE[rows * columns])
{
for (size_t i = 0; i < rows * columns; i++)
{
matrix[i] = source.matrix[i];
}
}
ArrayMatrix(ArrayMatrix && source):
rows(source.rows), columns(source.columns), matrix(source.matrix)
{
source.rows = 0;
source.columns = 0;
source.matrix = nullptr;
}
// and it also needs a destructor
~ArrayMatrix()
{
delete[] matrix;
}
TYPE & operator()(size_t row, size_t column)
{
// check bounds here
return matrix[row * columns + column];
}
TYPE operator()(size_t row, size_t column) const
{
// check bounds here
return matrix[row * columns + column];
}
// and also needs assignment and move operator
ArrayMatrix<TYPE> & operator=(const ArrayMatrix &source)
{
ArrayMatrix temp(source);
swap(*this, temp); // copy and swap idiom. Read link below.
// not following it exactly because operator=(ArrayMatrix source)
// collides with operator=(ArrayMatrix && source) of move operator
return *this;
}
ArrayMatrix<TYPE> & operator=(ArrayMatrix && source)
{
delete[] matrix;
rows = source.rows;
columns = source.columns;
matrix = source.matrix;
source.rows = 0;
source.columns = 0;
source.matrix = nullptr;
return *this;
}
size_t getRows() const
{
return rows;
}
size_t getColumns() const
{
return columns;
}
friend std::ostream & operator<<(std::ostream & out, const ArrayMatrix & in)
{
for (int i = 0; i < in.getRows(); i++)
{
for (int j = 0; j < in.getColumns(); j++)
{
out << in(i,j) << ' ';
}
out << std::endl;
}
return out;
}
//helper for swap.
friend void swap(ArrayMatrix& first, ArrayMatrix& second)
{
std::swap(first.rows, second.rows);
std::swap(first.columns, second.columns);
std::swap(first.matrix, second.matrix);
}
};
创建,其中之一是
Matrix<int> arr(rows, columns);
现在通过阵列周围是
void func(Matrix & arr);
使用数组是
int test = arr(row, column);
所有索引数学是隐藏从视线。
其它参考文献:
What is the copy-and-swap idiom?
What is The Rule of Three?
题外话:'INT矩阵[N] [M];'具有可变'N'和'M'是不合法的C++。它可以在一些编译器中进行扩展。谨慎并且不要指望它在移植到不同的编译器时工作。 – user4581301
也许这会有帮助吗? http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new –