什麼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 –