通常人们动态分配矩阵为
double **A;
int N,i,j;
N=10;
A = (double **)malloc(N*sizeof(double *));
for(i=0; i<N; i++)
{
A[i]= (double *)malloc(N*sizeof(double ));
}
根据类里面的一些讨论,我了解到这对于大型矩阵来说不是很有效。这会创建一个指向分配在内存中不同位置的数组的指针数组,在这种分配中更改行的成本更高。所以导师建议采用这种分配形式:
double *A;
int N;
N=10;
A = (double *)malloc(N*N*sizeof(double));
通过查看 A[N*i + j] 来访问矩阵的 i,j 元素。我想像这样分配我的矩阵,但我想保留我的旧符号 A[i][j]。因此,我想到的一种方法是首先进行错误分配,即创建双** A,如第一部分中所述。然后设置
A = (double **)malloc(N*sizeof(double *));
temp = (double *)malloc(N*N*sizeof(double ));
for(i=0; i<N; i++)
{
A[i]=&temp1[i*N+j];
}
这段代码似乎可以工作,但我只知道内存分配的基础知识,所以我想问一下这种分配是否有什么问题,它与仅保留数组 temp1 有什么不同吗?谢谢
最佳答案
这很容易做到,只需将 A
声明为指向行数组的指针即可:
double (*A)[N] = malloc(N*sizeof(*A));
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
A[i][j] = /*whatever*/;
}
}
如果您不清楚我使用的符号,请从内到外阅读:A
被定义为指向数组的指针 ((*A)
)的 N
个元素 ((*A)[N]
),其类型恰好是 double
(double (*A) [N]
)。该指针使用 malloc()
的返回值进行初始化(=
没有遵循标识符 A
可能会令人恼火,但是这个与 char myName[] = "Foo, Bar B.";
中的语法相同)。如果您拆分行和/或使用 typedef
,可能会更清楚:
double (*A)[N];
A = malloc(N*sizeof(*A));
或
typedef double MatrixLine[N];
MatrixLine* A = malloc(N*sizeof(*A));
在 C 中(不是在 C++ 中),即使 N
是动态计算的值,typedef
也能正常工作,我什至可以使用 typedef double MatrixLine[random( )];
,这并不是说它有多大意义...C 在这方面非常灵活!
了解如何将指针强制转换为 A 的类型可能也很有趣,以下是正确的强制转换:
double (*A)[N];
A = (double (*)[N])malloc(N*sizeof(*A));
请注意,转换的语法与 A
的声明完全相同,只是省略了标识符。
注1:
从 C99 开始,您可以在 for() 语句中直接声明循环变量。使用它,它可以使您的代码更具可读性。
注2:
在 C 中,不需要强制转换 malloc()
的返回值,并且无论如何也不会添加到您的代码中来编写它。但是,C++ 确实需要强制转换,因此如果您想在 C++ 项目中使用代码,请继续进行强制转换。
关于c - 关于矩阵的动态分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21971071/