通常人们动态地将矩阵分配为
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保持不同。感谢
答案 0 :(得分:2)
这很容易做到,只需将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
)({ {1}}),恰好是(*A)[N]
(double
)类型。此指针初始化为返回值double (*A)[N]
(malloc()
不遵循标识=
可能会令人恼火,但这与A
中的语法相同)。如果拆分线和/或使用char myName[] = "Foo, Bar B.";
:
typedef
或
double (*A)[N];
A = malloc(N*sizeof(*A));
在C(不是在C ++中)typedef double MatrixLine[N];
MatrixLine* A = malloc(N*sizeof(*A));
工作正常,即使typedef
是一个动态计算的值,我甚至可以使用N
,而不是它会有多大意义。 .C在这方面非常灵活!
知道如何将指针强制转换为A的类型也可能很有趣,这里包含了正确的强制转换:
typedef double MatrixLine[random()];
请注意,强制转换的语法与double (*A)[N];
A = (double (*)[N])malloc(N*sizeof(*A));
的声明完全相同,只是省略了标识符。
注1:
从C99开始,您可以在A
语句中声明循环变量。使用它,它使您的代码更具可读性。
注2:
在C中,不需要转换for()
的返回值,并且它不会添加到您的代码中来编写它。但是,C ++确实需要强制转换,所以如果你想在C ++项目中使用你的代码,请继续演员。