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,而不是 一堆的。然后,我可以执行以下操

关于矩阵和其他多维数组在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;
    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%的空间。当然,我自己做索引算术在道德上没有错。只是看起来很奇怪,显然没有人让编译器帮我做。你可以尝试在类后面抽象它。我相信你会找到一个优雅的方法编辑:事实上,另一个答案已经表明我可以定义