在循环中填充数组

时间:2016-01-18 13:01:58

标签: c arrays algorithm for-loop

我有一个不断被调用的函数。我有3个较小的数组,我需要在每个循环中打包成一个更大的数组

float* a;
float* b;
float* c;
float* abc;

a = calloc(1, sizeof(float)*3);
b = calloc(1, sizeof(float)*3);
c = calloc(1, sizeof(float)*3);
abc = calloc(1, sizeof(float)*9);


void update() {

   for(int i = 0; i < 3; i++) {
     fill_a(a);
     fill_b(b)
     fill_c(c);

     abc[0] = a[0];
     abc[1] = b[0];
     abc[2] = c[0];

     abc[0] = a[1];
     abc[1] = b[1];
     abc[2] = c[1];

     abc[0] = a[2];
     abc[1] = b[2];
     abc[2] = c[2];
   }
}

free(a);
free(b);
free(c);
free(abc);

上面的实现存在问题,因为在后续循环中会覆盖这些值。

我尝试在这样的值中添加偏移量:

   for(int i = 0; i < 3; i++) {
     fill_a(a);
     fill_b(b)
     fill_c(c);

     abc[(i*9)+0] = a[0];
     abc[(i*9)+1] = b[0];
     abc[(i*9)+2] = c[0];

虽然这似乎有用,但如果我尝试逐个添加也不起作用。

我还尝试通过索引值添加偏移量,但它会计入无穷大。

int idx = 0;

void update() {

   for(int i = 0; i < 3; i++) {
     fill_a(a);
     fill_b(b)
     fill_c(c);

     abc[++idx] = a[0];
     abc[++idx] = b[0];
     abc[++idx] = c[0];

     abc[++idx] = a[1];
     abc[++idx] = b[1];
     abc[++idx] = c[1];

我还尝试在一个for循环中填充第一个数组。然后在更新循环中将这些值放入更大的数组中。

int idx;

idx = 0;
void update() {

   for(int i = 0; i < 3; i++) {
     fill_a(a);
     fill_b(b)
     fill_c(c);
   }
  int tidx = idx;
  abc[++tidx] a[0];
  abc[++tidx] b[0];
  abc[++tidx] c[0];
  ....
  idx = tidx;
 }

但是idx再次运行到无穷大。我如何安排这个算法,以便我可以用较小数组中的值填充该循环内的较大数组,同时保持偏移顺序?

较大数组的值总是会被​​循环覆盖,所以在它被填充后,它会被其他地方消耗,然后覆盖下一次更新的调用。

修改 我已经尝试过gdb调试,一次调试代码一个变量。

预期的输出是这样的:

a = { 0, 1, 2 };
b = { -3, -2, -1 };

abc = { 0, -3, 11.
        1, -2, 22 };

这是一个来自实际代码的完整工作示例。

    int count = 3;
    float* v_buff;
    float* c_buff;

    size_t vs = sizeof(float) * 6);
    v_buff = calloc(1, (vs));


void update() {
     for(int i = 0; i < count; i++) {
         float a[3] = { 0, 1, 2}; //these will be new every update
         float b[3] = { -3, -2, -1};
         int idx = 0;
         v_buff[++idx] = a[0];
         v_buff[++idx] = a[1];
         v_buff[++idx] = a[2];

         v_buff[++idx] = b[0];
         v_buff[++idx] = b[1];
         v_buff[++idx] = b[2];
     }
}

该示例代码编译但同样适用。 尝试偏移:

v_buff[(i * 3) + (++idx)] = a[0];

导致我的计数器运行到无穷大或只是覆盖v_buff中的第一组值。

1 个答案:

答案 0 :(得分:2)

对于abc数组,第一种方法不起作用,因为您将数组的前3个条目设置为a的内容,然后使用{{b的内容覆盖它们。 1}},然后再次使用c

的内容

你的第二种方法很接近,但并不完全是因为你将i乘以9而不是3,所以索引在第一次迭代后超出界限。

您的第三种方法也很接近,但问题是您使用预增量(++idx)而不是后增量(idx++),因此您的索引从1到9而不是0到8。

此外,您的update功能正在循环中调用fill_afill_bfill_c。在没有看到这些功能的情况下,我猜测它每次都用相同的内容填充它们,所以那些可能不需要处于循环中。

因此,假设4个数组中每个数组的分配和释放发生在update之外,则该函数应如下所示:

void update()
{
    int i;

    fill_a(a);
    fill_b(b)
    fill_c(c);

    for(int i = 0; i < 3; i++) {
        abc[(i*3)+0] = a[i];
        abc[(i*3)+1] = b[i];
        abc[(i*3)+2] = c[i];
    }
}

在循环的第一次迭代中,i为0,因此三行评估为:

abc[0] = a[0];
abc[1] = b[0];
abc[2] = c[0];

在第二次迭代中,i为1,并且正文评估为:

abc[3] = a[1];
abc[4] = b[1];
abc[5] = c[1];

在第三次迭代中,i为2,并且正文评估为:

abc[6] = a[2];
abc[7] = b[2];
abc[8] = c[2];

你也可以像这样实现它:

void update()
{
    int i, idx;

    fill_a(a);
    fill_b(b)
    fill_c(c);

    for(int i = 0, idx = 0; i < 3; i++) {
        abc[idx++] = a[i];
        abc[idx++] = b[i];
        abc[idx++] = c[i];
    }
}