c在struct中定义具有不同大小的数组

我需要为两种类型的对象定义一个结构。 两者具有完全相同的数据结构并执行相同的任务(成员方法)。

唯一的区别是两种类型的数组大小不同,一种使用SIZE_A,另一种使用SIZE_B。

不需要复制结构和函数的定义。

我怎么能使用一种类型的’struct’,并初始化不同大小的数组?

#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){ ... 

我会在你的结构的末尾使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]) 

因此,要访问s *foomatr i行和 j列,以及它的 k 元素arr

 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 hack

 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中,使用大于0的值索引matr数组在技术上是访问超出其边界的对象。 然而,这是一种常见的做法,并且可以广泛使用。 C.99正式使用灵活的数组成员批准了该机制,尽管它需要在数组声明中不指定大小的语法。

即使使用联合,结构也将与两个数组中最大的一样大。

做其中一个:

  1. 忽略最大数组大小的开销。 (使用一个数组或联合)
  2. 为每种类型创建单独的结构。
  3. 使用malloc动态分配数组。

让数组成为指针并根据需要分配给它们(适当的大小)。 只有缩小尺寸才能访问2Darrays会有点笨拙。