我仍然不太了解矩阵和其他多维数组在C和C +中表示的方式以及如何动态分配它们。
考虑以下代码段:
int main()
{
int n;
cin >> n;
int a[n][n];
...
}
如果我理解正确,这会在堆栈上分配一个n乘n的整数矩阵。 可以使用[i] [j]访问矩阵的第(i,j)个元素。编译器 自动将其转换为对一个元素的第(n * i + j)个元素的访问 实际分配的维数组。
现在假设我想在堆上分配n×n矩阵a 堆栈。然后,我可以执行以下操作:
int main()
{
int n;
cin >> n;
int** a;
a = new int*[n];
for (int i=0;i<n;i++) a[i] = new int[n];
...
}
我现在可以再次作为[i] [j]访问第(i,j)个元素。但是,这并不完全正确 相当于上面的情况,因为我实际上必须为n * n int分配空间, 加上指向int的n个指针。此外,访问[i] [j]现在需要两次访问内存 只有一个。另一方面,避免了索引计算n * i + j。
现在假设我对m矩阵感兴趣,其中m很小,例如m = 2。 使用行指针数组然后浪费33%的空间。有什么办法吗? 避免这样做?
我当然可以分配一维数组并自己进行索引算法, 但这对我来说似乎不是最好的解决方案。
任何信息都将不胜感激!
答案 0 :(得分:1)
你可以做到
int *mat = new int[n*n];
然后使用mat[n*i+j]
答案 1 :(得分:1)
相反,你会分配一个int的线性数组:
int main()
{
int n;
cin >> n;
int *a;
a = new int[n*n];
}
自己做一个索引数学是一个很好的方法。
答案 2 :(得分:1)
您可以撤销分配顺序。如果您担心由于“行”指针而占用的内存占33%,或者为什么不将这些行转换为列,反之亦然?然后,您将使用[i][j]
访问元素,而不是[j][i]
。当然,这在您的情况下可能会或可能不实用,如果没有更多信息,很难说。
但实际上,我发现使用索引数学时没有任何问题,它没有任何内在错误。
答案 3 :(得分:1)
你可以创建一个为你做索引数学的课程,如果这是你不喜欢的地方。
class Matrix
{
public:
Matrix(int iRows, int iCols)
: mRows(iRows), mCols(iCols), m(new int[mRows*mCols]) { }
~Matrix() { delete [] m; }
int &element(int iRow, int iCol) { return m[iRow * mCols + iCol]; }
int mRows, mCols, *m;
};
答案 4 :(得分:0)
你做不到
int n;
cin >> n;
int a[n][n];
因为编译器需要在编译期间知道堆栈上需要的确切大小。当你在运行时要求它时,这是不可能的:-)另一方面,你可以做
#define N 10
int a[N][N];
在其他情况下,您必须使用动态分配。
在C中的分配就像你分配一个连续的内存一样,像[i] [j]这样的索引只是跳入那个内存的语法糖,你也可以做*(a + k * i + j),其中k是内部数组的大小。