2012-01-13 81 views
0

假設我有一組數組和字符串和常量:如何關聯一組變長變量?

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); 

但是,解決一般問題會做的任何整齊的方法。 我可以放在任何陣列的最大長度,雖然額外的功勞,如果我不必。 我對預處理器的技巧沒​​有任何問題,運行時初始化不會殺死我,儘管我寧願儘可能避免它。

回答

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; 
} 
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); 

注意,這表示是相當薄弱的,這將是更好的(但更復雜)來表示的大小整數向量太,因爲現在這是不可能知道有多少編號在運行時位於ab

更新:我定斷碼,我道歉。這就是我發佈未經測試的代碼所得到的結果。 :/

+0

你不能以這種方式初始化你的'struct'對象,成員是指針而不是數組。 – ouah 2012-01-13 11:40:09

+0

這將是美好的,但我似乎無法得到它編譯。 – 2012-01-13 11:41:22

+0

@JohnLawrenceAspden在C99中,您可以在@unwind代碼中使用複合文字作爲初始化符:像'(int [3]){4,3,2}'而不是'{4,3,2}' – ouah 2012-01-13 11:45:34

0

您可以創建一個結構類型來容納不同的成員。

作爲你的陣列具有不同的尺寸,使用指針和動態分配的陣列對象。

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

,如果你不想你構建結構通過動態分配ab陣列,您還可以初始化struct bla型與C99複合文字和C99指定的初始化的對象的對象。

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

您還應該添加struct成員來存儲數組對象的元素數。

+0

我可能需要將長度放在某個位置,我的聲明應該是什麼樣子? – 2012-01-13 11:42:09

+0

@JohnLawrenceAspden是的,你將不得不存儲長度(或者總是使用尾隨的空字符來標記字符串的結尾) – ouah 2012-01-13 11:48:36

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]); 
} 
+0

這是相當不錯的,但初始化是一團糟。我更喜歡定義一個未初始化的結構,並在函數調用中進行初始化:void init_obj(struct obj * obj,unsigned int num_a,const int * a,unsigned int num_b,const int * b,int c,const char * name) ;'在初始化過程中會被多次調用。 – ugoren 2012-01-13 13:09:30

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"); 
} 
+0

在我看來,一個好主意是讓大小字段的類型爲size_t而不是int。 – unwind 2012-01-13 13:11:23