我会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 的i
第 th行和j
th列,以及s *foo
'smatr
的k
第 th元素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;
}
这是一个 hack,因为在 C.89-90 中,matr
使用大于 的值索引数组在0
技术上访问超出其边界的对象。然而,这是一种常见的做法,并且可以广泛移植。C.99 正式批准了具有灵活数组成员的机制,尽管它需要在数组声明中不指定大小的语法。