3

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

唯一的区别是两种类型的数组大小不同,一种使用 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){
  ...
4

3 回答 3

4

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

执行以下操作之一:

  1. 忽略最大数组大小的开销。(使用一个数组或联合)
  2. 为每种类型创建一个单独的结构。
  3. 使用 动态分配数组malloc
于 2013-07-30T20:27:01.717 回答
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])

因此,要访问's 的i第 th行和jth列,以及s *foo'smatrk第 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 程序员经常使用所谓的structhack

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 正式批准了具有灵活数组成员的机制,尽管它需要在数组声明中不指定大小的语法。

于 2013-07-30T23:13:27.107 回答
1

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

于 2013-07-30T20:28:06.160 回答