c - 在 C 中动态设置数组访问模式

标签 c dynamic-memory-allocation

我想在 C(99) 中做这样的事情:

int n = compute_size_of_matrices();
int T = compute_number_of_matrices();
float matrices[][n][n] = malloc( sizeof(float) * n*n* T ); //[sic!]

观察第一个维度中缺失的尺寸。我想动态地设置维度的大小,以便执行如下操作

/* Load each matrix with the unit matrix */
for( int t = 0; t < T; t++ )
for( int i = 0; i < n; i++ )
for( int j = 0; j < n; j++ )
    matrices[t][i][j] = (i==j)?1.:0.;

当然,我可以简单地将“矩阵”分配为一维数组并使用一些索引魔法,但显然上述数组访问模式更方便。特别是,对于编译器来说,这不是什么技术黑魔法,除了记住动态数组大小的一些开销。是否有 GCC 的编译器扩展、某些方言功能或类似功能允许我执行上述操作?

与此相反,为了避免歧义,上述任务的常用 C 代码如下所示:

int n = compute_size_of_matrices();
int T = compute_number_of_matrices();
float* matrices = malloc( sizeof(float) * n*n* T ); //[sic!]
for( int t = 0; t < T; t++ )
for( int i = 0; i < n; i++ )
for( int j = 0; j < n; j++ )
    matrices[t*n*n + i*n + j] = (i==j)?1.:0.;

在真实的例子中,单字母变量可能有更多的名字,这很快就会使这样一段代码变得笨拙。

最佳答案

我发现的最好的

保留矩阵的数组大小属性(虽然不是矩阵的列表),并允许您使用 native 索引符号

  int n=5, T=2;
  float (*a)[n][n] = calloc(T,sizeof(float[n][n])); // <== initializes to 0!
  for (size_t t=0; t<T; ++t) 
    for (size_t i=0; i<n; ++i)
      a[t][i][i] = 1.0;   // <== only set the 1's

指向二维数组的指针的声明是棘手的部分,但是 calloc(见下文)会为您处理零初始化,因此您只需设置非零元素。

当然,当您尝试传递这些东西时,有趣的部分就来了……但是如果您小心声明并且使用的是 c99,您可以做出以下任一

void foo(int n, float (*a)[n][n]) {
  // ...
}

void bar(int t, int n, float a[t][n][n]) {
  // ...
}

工作。 (实际上 gcc 会让你逃脱,除非你使用 -std=c89 -pendantic...)

次之,但它适用于 ansi-c

您当然可以使传统版本(带有丑陋的手标)更易于阅读。

int n = compute_size_of_matrices();
int T = compute_number_of_matrices();
float* matrices = calloc(T,  sizeof(float) * n*n); // <== initializes to 0!
for( int t = 0; t < T; t++ )
   for( int i = 0; i < n; i++ )
    matrices[t*n*n + i*n + i] = 1;  // <== only set the 1's

嗯,这似乎是个好主意...

唉,c不会让你做的

  int n=5, T=2;
  float matrices[T][n][n] = {};  // <== ***ERROR!!!***

这将使您保持矩阵的“数组性”并且更加清晰。

速度慢吗?

因为 calloc 将使用一些高度优化的系统内存编写器来设置为 0,所以您不会受到很大的速度影响。

关于c - 在 C 中动态设置数组访问模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7424769/

相关文章:

realloc() 可以扩展到(并覆盖)后续数据吗?

c - 从标准输入检索字符

c - C中不完整类型和对象类型的定义是什么?

c++ - 文件输入错误

c - c中的strlen函数

c - 修改函数中的指针

c - 在传递给函数本身的指针上调用 realloc() 是否安全?

html - C 到 HTML 中的自动制表符

c - 动态数组的收缩因子?

c++ - 供应商是否将 new 和 malloc 实现为小对象分配器?