Как я могу связать набор переменных переменной длины? - PullRequest
0 голосов
/ 13 января 2012

Предположим, у меня есть набор массивов, строк и констант:

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, 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 ]

4 голосов
/ 13 января 2012

Используйте структуру:

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 или b во время выполнения .

ОБНОВЛЕНИЕ : Я исправил неработающий код, мои извинения. Вот что я получаю от публикации непроверенного кода. : /

0 голосов
/ 14 января 2012

Вот комбинация всех ответов до сих пор с тестовым циклом.

Это то, что я на самом деле собираюсь использовать, я думаю.Спасибо всем за помощь!

#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;
}
0 голосов
/ 13 января 2012

Альтернативная версия, сочетающая различные вклады 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");
}
0 голосов
/ 13 января 2012

Это комбинация ответа раскрутки и комментария Уаа:

Поиск хорошего способа избавления от повторяющихся массивов в объявлениях закончил бы работу.

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] );
}
0 голосов
/ 13 января 2012

Вы можете создать тип структуры для хранения различных элементов.

Поскольку ваши массивы имеют разные размеры, используйте указатели и динамически размещайте объекты массива.

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

если вы не хотите создавать свой объект struct путем динамического выделения массивов a и b, вы также можете инициализировать объекты типа struct bla с помощью составных литералов C99 и обозначенных инициализаторов C99.

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

Вы также должны добавить членов структуры для хранения количества элементов ваших массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...