使用结构来访问C中的数组

时间:2011-12-12 18:07:49

标签: c arrays structure

我理解如何创建可用于访问数组的结构,例如:

#include <stdio.h>

typedef struct {
  int i;
  int j;
  int k;
} MyStruct;

int main()
{
  MyStruct *ms;
  int array[9];
  int i;

  for(i=0;i<9;++i) array[i] = i;

  ms = (MyStruct *)array;

  for(i=0;i<3;++i) printf("%d %d %d %d\n",i,ms[i].i,ms[i].j,ms[i].k);
  return 0;
}

允许我以ms [1] .i和数组[1]的形式访问数组[0]为ms [1] .j等。但是,如果我想使用数组,怎么能做同样的事情在运行时已知但在编译时不知道的结构中?类似的东西:

#include <stdio.h>

typedef struct {
  int *myArgs;
} MyStruct;

int main()
{
  MyStruct *ms;
  int array[9];
  int i;

  for(i=0;i<9;++i) array[i] = i;

  ms = (MyStruct *)array;

  for(i=0;i<3;++i) printf("%d %d %d %d\n",i,ms[i].myArgs[0],ms[i].myArgs[1],ms[i].myArgs[2]);
  return 0;
}

在这个例子中,我会在运行时知道myArgs的长度为3.但是myArgs的长度也可能为9,在这种情况下,ms应该是长度为1.

修改

我正在为PDE求解器存储一个解决方案集,该求解器具有许多固定编译时知识,然后是未知数量的附加内容。例如,我的数组将具有X,Y,Z,但之后它可能会有3或5或10个更多的东西。因此,我想提供一种结构,可以在以后提供对字段的访问以便于阅读,例如solution.x,solution.y,solution.z,solution.chemicalSpecies [0],solution.chemicalSpecies [1]等。在编译时,物种的数量是完全未知的。

我正在使用一个外部库来存储未知数作为数组,我可以以[k] [j] [i] [numUnknowns]的形式返回数组,这样可以提供访问权限像解决方案[k] [j] [i] .something。

3 个答案:

答案 0 :(得分:1)

通常,给定数组大小NmyArgs < N,您将拥有N/myArgs个完整的数据集,其余的N%myArgs项。你可以根据这个事实建立数组索引。

然而,这段代码看起来像是一场噩梦。你想达到什么目的?可能有更好的方法。

答案 1 :(得分:1)

没有

在第一种情况下,结构的大小是3 int个变量的大小。当您将数组的指针强制转换为结构的指针时,每个3 int个元素将与一个MyStruct元素匹配,代码中的魔力是什么(理论上是不可移植的)

在第二种情况下,结构的大小是指向int的1指针的大小。您必须意识到指针与数组在使用方面有一些相似之处,但它们不是一回事。指针只是一个变量,其中一个值指向内存地址。然后该地址的内容可以用作数组。

在C中,结构和数组大小是在编译时处理的,因此结构的大小在运行时不会改变,因此在结构中有一个指针对你的purpuse没有好处,因为指针大小也是固定的。 / p>

对您来说,一个好的解决方案可能是使用抽象数据类型,例如:

typedef struct {
  int m; /* number of lines */
  int n; /* number of columns */
  int *data; /* pointer to the actual data */
} Matrix;

然后你可以创建使用struct的辅助函数:

void matrix_new(Matrix *m, int rows, int columns);
int matrix_get(Matrix *m, int i, int j);
void matrix_set(Matrix *m, int i, int j, int value);
void matrix_free(Matix *m);

如果这太笨拙,你甚至可以使用混合方法(不是太“抽象”类型):

int matrix_get(Matrix *m, int i, int j)
{
  return m->data[i * m->n + j];
}

int main()
{
  Matrix m;
  int array[9];
  int i;

  for(i=0;i<9;++i) array[i] = i;

  m.m = m.n = 3;
  m.data = array;

  for(i=0;i<3;++i)
    printf("%d %d %d %d\n", i,
                            matrix_get(&m, i, 0),
                            matrix_get(&m, i, 1),
                            matrix_get(&m, i, 2));
  return 0;
}

答案 2 :(得分:0)

鉴于您的澄清,我会解决以下问题。我有一个包含固定的x,y和z的结构,然后是一个指向数组的指针,您可以将其设置为解决方案数组中相应点的位置。像这样:

struct MyStruct {
    int x, y, z;
    int *extras;
};

...
int solutions[9];
struct MyStruct ms;
ms.x = solutions[0];
ms.y = solutions[1];
ms.z = solutions[2];
ms.extras = (solutions + 3);
...

这样,您可以轻松访问所需的字段,以及其他内容:

ms.extras[0]

至少那应该可以起作用,从头到尾。

如果我是你,我也会在结构中输入num_extras,这样你就不会跑掉数组的末尾。

修改:如果您希望将它们镜像,则可以改为:

struct MyStruct {
    int *x, *y, *z;
    int *extras;
};

然后:

...
int solutions[9];
struct MyStruct ms;
ms.x = &solutions[0];
ms.y = &solutions[1];
ms.z = &solutions[2];
ms.extras = (solutions + 3);
...

但这很像以前的情况,不是吗?