如何关联一组变长变量?

时间:2012-01-13 11:25:11

标签: c arrays object associations struct

假设我有一组数组,字符串和常量:

const int a[]={0x01, 0x02};
const int b[]={2,0};
const int c=234;
const char* name="foo";

一起组成对象foo。

还有许多类似的对象,例如

const int a[]={0x04, 0x02, 0x03};
const int b[]={2,0,1};
const int c=1234;
const char* name="arfle";

在C中声明这些对象的最佳方法是什么? (特别是gcc,我对gcc-only扩展,c99等没问题。)

我希望像

这样的东西
thing[0]={a={0x04, 0x02, 0x03}, b={2,0,1}, c=1234, name="arfle"};
thing[1]={a={0x01, 0x02}, b={2,0}, c=234, name="foo"};

printf("%s", thing.name);

但任何解决一般问题的巧妙方法都可以。 我可以在任何阵列上放置最大长度,但如果我不需要额外的功劳。 我对预处理器技巧没有任何问题,并且运行时初始化不会杀死我,尽管如果可能的话我宁愿避免它。

5 个答案:

答案 0 :(得分:4)

使用结构:

struct object
{
  int *a;
  int *b;
  int c;
  const char *name;
}

int arfle_a[] = { 4, 3, 2 };
int arfle_b[] = { 2, 0, 1 };
int foo_a[] = { 1, 2 };
int foo_b[] = { 2, 0 };
struct object thing[] = {
  { arfle_a, arfle_b, 1234, "arfle" },
  { foo_a, foo_b, 234, "foo" },
};

printf("%s\n", thing[1].name);

请注意,此表示非常弱,表示具有大小的整数向量会更好(但更复杂),因为现在无法知道a或{{1中有多少个数字在运行时。

更新:我修复了破损的代码,道歉。这就是我发布未经测试的代码所得到的。 :/

答案 1 :(得分:0)

您可以创建一个结构类型来保存不同的成员。

由于您的数组大小不同,请使用指针并动态分配数组对象。

struct bla {
    const int *a;
    const int *b;
    int c;
    const char *name;
};

如果您不想通过动态分配ab数组来构造struct对象,还可以使用C99复合文字初始化struct bla类型的对象并指定C99初始化。

struct bla a = {.a = (const int [3]) {4, 2, 3},
                .b = (const int [2]) {2, 0},
                .c = 42,
                .name = "arfle"}; 

您还应该添加struct成员来存储数组对象的元素数。

答案 2 :(得分:0)

这是放松回答和ouah的评论的组合:

找到摆脱声明中重复数组的好方法可以完成这项工作。

struct object
{
  int *a;
  int sizeof_a;
  int *b;
  int sizeof_b;
  int c;
  const char *name;
};

struct object thing[] = {
  { (int[]){ 4, 3, 2 }, sizeof((int[]){ 4, 3, 2 }), (int[]){ 2, 0, 1 }, sizeof((int[]){ 2, 0, 1 }), 1234, "arfle" },
  { (int[]){ 1, 2 }, sizeof((int[]){ 1,2 }), (int[]){ 2, 0 }, sizeof((int[]){ 2, 0 }), 234, "foo" },
};

void test(void) {
  int i;
  printf("%s\n", thing[1].name);
  for(i=0; i<thing[1].sizeof_a; i++)
    printf("%d, ", thing[1].a[i] );
}

答案 3 :(得分:0)

另一个版本,结合了cnicutar,ouah和unwind的各种贡献。我不确定额外的冗长是好还是坏。

struct object
{
  int *a;
  int sizeof_a;
  int *b;
  int sizeof_b;
  int c;
  const char *name;
};

struct object thing[] = {
  { .a=(int[]){ 4, 3, 2 }, .sizeof_a=sizeof((int[]){ 4, 3, 2 }), .b=(int[]){ 2, 0, 1 }, .sizeof_b=sizeof((int[]){ 2, 0, 1 }), .c=1234, .name="arfle" },
  { .a=(int[]){ 1, 2 }, .sizeof_a=sizeof((int[]){ 1,2 }), .b=(int[]){ 2, 0 }, .sizeof_b=sizeof((int[]){ 2, 0 }), .c=234, .name="foo" },
};

void test(void) {
  int i;
  printf("%s\n", thing[1].name);
  for(i=0; i<thing[1].sizeof_a; i++)
    printf("%d, ", thing[1].a[i] );
  printf("\n");
}

答案 4 :(得分:0)

到目前为止,这是所有答案的组合,带有测试循环。

我认为这就是我实际要使用的内容。谢谢大家的帮助!

#include<stdio.h>

typedef struct object_s
{
  int *a;
  size_t sizeof_a;
  int *b;
  size_t sizeof_b;
  int c;
  const char *name;
} object_t ;

#define DECLARE_OBJECT(a,b,c,d)   { (a), (sizeof(a)/(sizeof(int))),(b), sizeof(b)/(sizeof(int)), (c),(d)}

object_t thing[] = {
  DECLARE_OBJECT(((int[]){4,3,2}), ((int[]){ 2, 0, 1 }), 1234, "arfle"),
  DECLARE_OBJECT(((int[]){1,2})  , ((int[]){ 2, 0 })   ,  234, "foo")
};

int main(void) {
  int i,j;
  for(j=0; j<((sizeof(thing)/(sizeof(object_t)))); j++){
    printf("%s\n", thing[j].name);
    for(i=0; i<thing[j].sizeof_a; i++) printf("%d, ", thing[0].a[i] );
    printf("\n");
    for(i=0; i<thing[j].sizeof_b; i++) printf("%d, ", thing[0].b[i] );
    printf("\n");
    printf("%d\n",thing[j].c);
  }
    return 0;
}