2013-07-30 43 views
3

我需要爲兩種類型的對象定義一個結構。兩者具有完全相同的數據結構並執行相同的任務(成員方法)。c在結構中定義不同大小的數組

唯一的區別是兩種類型的數組大小不同,一種使用SIZE_A,另一種使用SIZE_B。

不需要複製結構和函數的定義。

我怎麼能使用一種'結構',並初始化其大小不同的數組?

#define SIZE_A 100 
#define SIZE_B 200 

typedef struct{ 
    int matr[SIZE_A][SIZE_A]; // for another type matr[SIZE_B] 
    int arr[SIZE_A];   // for another type arr[SIZE_B] 
    int size;     // will be initialized to SIZE_A or SIZE_B 
    int var1, var2; 
}s; 

void task1(s* si){ 
    ... 
} 

void task2(s* si){ 
    ... 
+2

如果內存不連續,你關心嗎? – Magn3s1um

+0

不,沒有特別的限制。 – lukmac

回答

2

我會讓matr一個靈活的數組在結尾。然後,我會將arr陣列粘貼到matr的最後一行。

typedef struct { 
    int size; 
    int var1, var2; 
    int matr[]; 
} s; 

static inline int size_ok_s (int size) { 
    switch (size) { 
    case SIZE_A: 
    case SIZE_B: 
     return 1; 
    default: 
     break; 
    } 
    return 0; 
} 

s * create_s (int size) { 
    s *x = 0; 
    if (size_ok_s(size)) { 
     x = malloc(sizeof(*x) + sizeof(int[size+1])); 
     if (x) x->size = size; 
    } 
    return x; 
} 

爲了實現一個統一的接口,你可以使用宏:

#define s_matr(x) ((int (*)[(x)->size])(size_ok_s((x)->size) ? (x)->matr : 0)) 
#define s_arr(x) (s_matr(x)[(x)->size]) 

因此,訪問ijs *foomatr列,其ktharr的元素:

s *foo = create_s(SIZE_A); 
/* ... */ 
    s_matr(foo)[i][j] = 0; 
    s_arr(foo)[k] = 0; 

彈性陣列成員是在§ 6.7.2.1 ¶ 16描述的C.99一個新功能之前C.99,經常使用C程序員什麼被稱爲struct

typedef struct { 
    int size; 
    int var1, var2; 
    int matr[1]; 
} s; 

s * create_s (int size) { 
    s *x = 0; 
    if (size_ok_s(size)) { 
     x = malloc(sizeof(*x) + sizeof(int[size])); 
     if (x) x->size = size; 
    } 
    return x; 
} 

從C.89-90開始,這是一個黑客技術,對matr數組進行索引的值大於0,它在技術上訪問超出其邊界的對象。然而,這是一種常見的做法,並且具有廣泛的便攜性。 C.99正式批准了靈活數組成員的機制,儘管它需要在數組聲明中沒有指定大小的語法。

5

即使使用聯合,結構也會與兩個數組中的最大值一樣大。

執行下列操作之一:

  1. 忽略最大的數組大小的開銷。 (使用一個數組或聯合)
  2. 爲每種類型創建一個單獨的結構。
  3. 動態分配數組malloc
+0

我想選擇'2',但這意味着我必須複製函數,例如:void task1(struc_a * s); void task1(struct_b * s),...有很多任務,所以重複它們並不好。這讓我想到使用選項'1'和'3'。 – lukmac

+0

@lukmac正確,除非差別很大,否則我會推薦1.如果它很大,也許3.也可以。 –

1

讓數組成爲指針並根據需要分配給它們(合適的大小)。只有縮小規模才能進入二維數組將會有點笨拙。

+0

「讓數組成爲指針」有點讓人誤解。數組不是指針。 –

+0

由於數組元素僅僅是數組基地址的偏移量,因此將'數組'(而不是第一個元素)視爲基地址並不合邏輯。然而,爲了更改,請將地址存儲在大小爲'elements * sizeof(type)''的malloc'數組中。 –