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 *foo
的matr
第 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正式使用灵活的数组成员批准了该机制,尽管它需要在数组声明中不指定大小的语法。
即使使用联合,结构也将与两个数组中最大的一样大。
做其中一个:
- 忽略最大数组大小的开销。 (使用一个数组或联合)
- 为每种类型创建单独的结构。
- 使用
malloc
动态分配数组。
让数组成为指针并根据需要分配给它们(适当的大小)。 只有缩小尺寸才能访问2Darrays会有点笨拙。