C++ C+中的矩阵与数组的数组+;以及它们的动态分配
关于矩阵和其他多维数组在C和C+中的表示方式以及如何动态分配,我仍然不太了解 考虑以下代码段:C++ C+中的矩阵与数组的数组+;以及它们的动态分配,c++,matrix,allocation,C++,Matrix,Allocation,关于矩阵和其他多维数组在C和C+中的表示方式以及如何动态分配,我仍然不太了解 考虑以下代码段: int main() { int n; cin >> n; int a[n][n]; ... } 如果我理解正确,这将在堆栈上分配一个n乘n的整数矩阵。 矩阵的第(i,j)个元素可以使用[i][j]来访问。编译程序 自动将其转换为1的第(n*i+j)个元素的访问 实际分配的多维数组 假设现在我想在堆上分配n×n矩阵a,而不是 一堆的。然后,我可以执行以下操
int main()
{
int n;
cin >> n;
int a[n][n];
...
}
如果我理解正确,这将在堆栈上分配一个n乘n的整数矩阵。
矩阵的第(i,j)个元素可以使用[i][j]来访问。编译程序
自动将其转换为1的第(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];
...
}
intmain()
{
int n;
cin>>n;
国际**a;
a=新整数*[n];
对于(inti=0;i你可以
int *mat = new int[n*n];
然后使用mat[n*i+j]
你可以做的
int *mat = new int[n*n];
然后使用mat[n*i+j]
而不是分配一个整数线性数组:
int main()
{
int n;
cin >> n;
int *a;
a = new int[n*n];
}
自己做索引数学是一个很好的方法。相反,您应该分配一个整数线性数组:
int main()
{
int n;
cin >> n;
int *a;
a = new int[n*n];
}
自己做索引数学是一个很好的方法。你做不到
int n;
cin >> n;
int a[n][n];
因为编译器需要知道编译时堆栈上需要的确切大小。当您在运行时要求它时,这是不可能的:-)另一方面,您可以这样做
#define N 10
int a[N][N];
在其他情况下,您必须使用动态分配
C中的分配就像分配一块连续内存一样,像[i][j]这样的索引只是跳入该内存的语法糖,你也可以这样做*(a+k*i+j),其中k是内部数组的大小。你不能这样做
int n;
cin >> n;
int a[n][n];
因为编译器需要知道编译时堆栈上需要的确切大小。当您在运行时要求它时,这是不可能的:-)另一方面,您可以这样做
#define N 10
int a[N][N];
在其他情况下,您必须使用动态分配
C中的分配就像分配一块连续内存一样,像[i][j]这样的索引只是跳入该内存的语法糖,你也可以这样做*(a+k*i+j),其中k是内部数组的大小。您可以颠倒分配顺序。如果您担心“行”指针占用33%或任何内存,为什么不直接将行转换为列,反之亦然?然后,您可以使用[j][i]访问元素,而不是[i][i]
。当然,在您的情况下,这可能是可行的,也可能不可行,如果没有更多信息,很难说
但实际上,我认为使用索引数学没有问题,它本身没有什么问题。您可以颠倒分配顺序。如果您担心“行”指针占用33%或任何内存,为什么不直接将行转换为列,反之亦然?那么,而不是[I][j]
您可以使用[j][i]
访问元素。当然,在您的情况下,这可能实用,也可能不实用,没有更多信息很难说
但实际上,我认为使用索引数学没有问题,它本身没有什么问题。如果你不喜欢的话,你可以创建一个为你做索引数学的类
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;
};
如果你不喜欢的话,你可以创建一个为你做索引数学的类
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;
};
我不确定您的第一个代码(带有a[n][n]
的声明)是否可以工作我测试了它,它确实可以工作。我还尝试分配了两个这样的n乘n矩阵,地址差为4(nn+1)。这似乎表明确实分配了nn int。我不确定为什么会出现1。您不应该关心1(编译器可能会强制本地数据对齐)。我不确定您的第一个代码(带有a[n][n]
的声明)是否工作。我测试了它,它确实工作。我还尝试分配了两个这样的n乘n矩阵,地址差为4(nn+1)。这似乎表明确实分配了nn int。我不确定为什么会出现1。您不应该关心1(编译器可能会强制本地数据对齐).我在问题的结尾提到了这个选项。我很想知道是否有一种方法可以避免自己做索引数学。我在问题的结尾提到了这个选项。我很想知道是否有一种方法可以避免自己做索引数学。是的,我在文章的结尾回避了这种可能性。没有其他选择吗ion?是的,我在我的文章末尾回避了这种可能性。没有其他选择吗?我使用g++编译器检查了上面的代码,它确实有效!请您自己检查它。无论如何。感谢您的帮助!啊,这是答案,感谢链接!这确实澄清了堆栈上的分配情况。甚至虽然它不是标准的,但它似乎与g++一起工作。因为它不是标准的,所以使用它可能不是一个好主意。我使用g++编译器检查了上面的代码,它确实工作了!请您自己检查它。无论如何。谢谢您的帮助!啊,这是答案,谢谢链接!这确实澄清了情况在堆栈上的分配。虽然它不是标准的,但似乎与g++一起工作。由于它不是标准的,使用它可能不是一个好主意。颠倒索引顺序是一个好主意。它不能完全解决问题,因为在动态设置中,有时行更多,有时列更多。此外,如果我想存储很多2乘2的矩阵,那么在任何情况下都会浪费33%的空间。当然,我自己做索引算术在道德上没有错。只是看起来很奇怪,显然没有人让编译器帮我做。你可以尝试在类后面抽象它。我相信你会找到一个优雅的方法编辑:事实上,另一个答案已经表明我可以定义