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

时间:2013-07-30 20:25:07

标签: 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){
  ...

3 个答案:

答案 0 :(得分:5)

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

做其中一项:

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

答案 1 :(得分: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])

因此,要访问i j的{​​{1}} th 行和s *foo th 列,及其matr的{​​{1}} th 元素:

k

灵活数组成员是§6.7.2.1¶16中描述的C.99的新功能。在C.99之前,C程序员经常使用所谓的 arr hack

s *foo = create_s(SIZE_A);
/* ... */
    s_matr(foo)[i][j] = 0;
    s_arr(foo)[k] = 0;

这是一个黑客攻击,因为在C.89-90中,使用大于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.99正式批准了使用灵活数组成员的机制,尽管它需要在数组声明中不指定大小的语法。

答案 2 :(得分:1)

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