通过引用传递静态二维结构数组

时间:2015-07-03 08:01:36

标签: c arrays function pointers struct

我尝试传递静态二维结构作为函数的引用。 但我不知道如何以正确的方式完成这项工作。

根据我的理解,我将指针传递给struct test的第一个元素到initfield()。 C确实知道结构测试的大小,所以我可以跳转到数据的特定请求位置。我只是不知道如何处理所需的数据。

这是我希望能够描述我正在寻找的代码。

struct test{
int i;
double d;
};

void initfield(struct test *a, int structsize)
{
    int i, j;
    for (i = 0; i < structsize; i++)
    {
        for (j = 0; j < structsize; j++)
        {
            a[i][j]->i = 1;
            a[i][j]->d = 1.0;
        }
    }
}

int main(void)
{
    int i, j;
    struct test field[8][8];
    initfield(field, 8);
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {
            printf("test[%i][%i].i = %i", i, j, test.i);
            printf("test[%i][%i].d = %i", i, j, test.d);
        }
    }
    return 0;
}

更新:

我已将printf替换为以下内容:

printf("test[%i][%i].i = %i", i, j, field[i][j].i);
printf("test[%i][%i].d = %lf", i, j, field[i][j].d);

但是,我仍然遇到initfield错误。

5 个答案:

答案 0 :(得分:1)

问题实际上在您的initfield()代码

 void initfield(struct test *a, int structsize)

a的类型为struct test *,之后您正在进行

 a[i][j]->i = 1;

预计astruct test **

那就是说,

for (j = 0; j < 8; j++)
    {
        printf("test[%i][%i].i = %i", i, j, test.i);
        printf("test[%i][%i].d = %i", i, j, test.d);
    }

完全错了。也没有任何名为test变量,也无法使用structVar.membervar格式访问二维数组。此外,您正在使用%d打印double,而initfield()会调用undefined behaviour

解决方案:您可以使用数组属性和指针算法来实现您想要的效果。

您必须更改for (i = 0; i < structsize; i++) { for (j = 0; j < structsize; j++) { ((a+(i*structsize))+j)->i = 7; //I changed the value to store, just like that ((a+(i*structsize))+j)->d = 2.0; //I changed the value to store, just like that } } 代码中的循环,例如

main()

并在%f中使用www.domain.com www.domain.es www.domain.it and so on... 打印值。

A Live variant

答案 1 :(得分:0)

你假设C可以发现a里面指的是一个边长为structsize的正方形数组,尽管你清楚地说a有类型&#34;指向struct test&#34;的指针,这是不一样的。

您需要在函数内手动执行索引:

static void initfield(struct test *a00, size_t sidelength)
{
  for(size_t i = 0; i < sidelength; ++i)
  {
    for(size_t j = 0; j < sidelength; ++j)
    {
      struct test *aij = a00 + i * sidelength + j;
      aij->i = 1;
      aij->j = 1.0;
    }
  }
}

我没有测试上面的内容,但是这样的事情应该有效。它基本上只使用简单的指针算法来计算(i,j)处的2D数组元素的地址,给定(0,0)处的地址。

答案 2 :(得分:0)

首先,structsize不是一个好的标识符名称。它不是结构的大小,而是数组的一个维度的大小。我将使用参数xy,或widthheigth或两个维度的更好名称来实现它。

field也是一个坏名字。字段通常用于调用struct的成员。使用标识符field来调用struct s数组的数组非常令人困惑。

然后问题:field是一个结构数组的数组。在函数参数中,这相当于指向指针的指针。

initfield的第一个参数应为struct test **类型。然后在函数中,您使用[]运算符取消引用两次:

  • a的类型为struct test **
  • a[i]的类型为struct test *
  • a[i][j]的类型为struct test

要访问a[i][j]字段,您需要.运算符,因为它是struct testa[i][j].d。如果->类型为a[i][j],则运算符struct test *将起作用,但不是。

在这种情况下并不重要:正如其他人所说的那样,如果不借助第一维的大小明确计算,则无法访问数组的第二维。 a[i][j]不起作用,您需要某种指针算法:struct test *p = a + i * structsize + j并使用p->ip->d

在主要功能中,field的尺寸已知,因此field[i][j].d有效。

答案 3 :(得分:0)

它工作正常我没想过自己计算地址。 非常感谢!

这是我的最终改编代码,它完美无缺!

struct test{
int i;
double d;
};

void initfield(struct test *a00, int structsize)
{
    int i, j;
    for (i = 0; i < structsize; i++)
    {
        for (j = 0; j < structsize; j++)
        {
            struct test *acurrent = a00 + i * structsize + j;
            acurrent->i = 1;
            acurrent->d = 1.0;
        }
    }
}

int main(void)
{
    int i, j;
    struct test field[8][8];
    initfield(&field[0][0], 8);
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
        {
            printf("test[%i][%i].i = %i\n", i, j, field[i][j].i);
            printf("test[%i][%i].d = %lf\n", i, j, field[i][j].d);
        }
    }
    return 0;
}

答案 4 :(得分:0)

最好的方法:

void initfield(size_t x, size_t y, struct test a[x][y]);

请注意,C很奇怪,上面仍然是一个指针,相当于struct test*。如果您希望拥有真正的数组指针类型,则必须执行以下操作:

void initfield(size_t x, size_t y, struct test a[x][y])
{
  struct test (*ptr)[x][y] = (void*)a;

或者最好:

struct test (*ptr)[y] = *a;
ptr[i][j] = something; // use the array pointer with sane syntax