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])
i
したがって、 の番目の行とj
番目の列、および のs *foo
番目の要素にアクセスするには:matr
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
ハックと呼ばれるものをよく使用していました。
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 では、柔軟な配列メンバーを使用してメカニズムを正式に認可しましたが、配列宣言でサイズを指定しないという構文が必要です。