关于矩阵的动态分配

时间:2014-02-23 16:37:20

标签: c arrays matrix

通常人们动态地将矩阵分配为

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保持不同。感谢

1 个答案:

答案 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 ++项目中使用你的代码,请继续演员。