动态设置数组访问模式用C [英] Dynamically set array access pattern in C

查看:192
本文介绍了动态设置数组访问模式用C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to do something like this in 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,一些方言特征或类似的编译器扩展,让我做一些像上面?

Of course, I could simply allocate 'matrices' as a one-dimensional array and use some index magic, but obviously the above access pattern to the array is way more convenient. In particular, it is no technical black magic for the compiler, except some overhead to remember the dynamic array sizes. Is there a compiler extension of GCC, some dialect feature or similar which allows me to do something like above?

在此相反,为了避免歧义,通常C code表示上述任务是这样的:

In contrast to this, and in order to avoid ambiguity, a usual C code for the above task would look like this:

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.;

在实际例子中,单字母的变量可能会有更多冠冕堂皇的名称,并迅速呈现这样一块code的笨拙。

In real examples, the one-letter variables might have more sounding names, which quickly renders such a piece of code clumsy.

推荐答案

preserves的基质中的数组大小属性(虽然不是的列表的矩阵),并允许您使用本机索引符号

Best I've found

Preserves the array size attributes of the matricies (though not of the list of matrices), and lets you use the native indexing notation

  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 (见下文)负责零初始化你,所以你只设置非零元素

The declaration of the pointer to the 2d arrays is the tricky part, but calloc (see below) takes care of the zero initialization for you, so you only set the non-zero elements.

当然,最有趣的部分来当您尝试通过周围这些东西......但如果​​你小心你的申报和使用C99可以使任

Of course, the fun part comes when you try to pass these things around...but if you are careful with your declaration and are using c99 you can make either of

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

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

工作。 (其实 GCC 会让你得逞的,除非你使用 -std = C89 -pendantic ...)

work. (Actually gcc will let you get away with unless you use -std=c89 -pendantic...)

您绝对可以让传统的版本(与丑陋的手索引)更易于阅读。

You can certainly make the traditional version (with ugly hand indexing) easier to read.

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

那么,它的显得的是一个好主意...

唉Ç不会让你做

Well, it seemed like a good idea...

Alas c won't let you do

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

这将让你保持基质中的arrayness,并更加清晰。

which would let you keep the "arrayness" of matricies and be even clearer.

由于释放calloc 将使用一些高度优化的系统内存作家设置为0,你不会冒很大的速度冲击。

Because calloc will use some heavily optimized system memory writer to set to 0 you won't be taking a big speed hit.

这篇关于动态设置数组访问模式用C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆