4

我试图想出一种方法来声明几个数据结构,这些数据结构是结构数组,其中每个后续数组都使用先前数组的一部分。减少重复的方法。这样每个元素只声明一次。

所以从概念上讲,想象这四个数组,其中出现在两个数组中的给定元素编号意味着表示实际相同的事物,而不仅仅是具有相同值的另一个。

some_type group_A[] = {
    elt0, elt1, elt2, elt3, NULL
};

some_type group_B[] = {
    elt0, elt1, elt2, elt3,  // those are all A's
    elt4, elt5, NULL         // these are new to B
};

some_type group_C[] = {
    elt0, elt1, elt2, elt3,  // those are all A's
    elt6, elt7, elt8, NULL   // these are new to C
};

some_type group_D[] = {
    elt0, elt1, elt2, elt3, elt4, elt5, // those are all B's
    elt9, elt10, elt11, NULL            // these are new to D
};

您可以假设它some_type已经是某种结构的 typedef。

我想做的是消除多余的声明,因为它们总体上看起来不整洁,而且它们让你可以更新不连贯性。这是更紧凑的表示,其中组中的条目可以是普通元素,也可以是对此类元素的另一个数组的引用。

(你可以通过最后的 NULL 指针推断出每个数组声明每个元素实际上是指向相同类型结构的指针是正确的。)

some_type group_A[] = {
    elt0, elt1, elt2, elt3, NULL
};

some_type group_B[] = {
    Group_A, elt4, elt5, NULL
};

some_type group_C[] = {
    Group_A, elt6, elt7, elt8, NULL
};

some_type group_D[] = {
    Group_B, elt9, elt10, elt11, NULL
};

换句话说,我想要一种方法来声明 Group_B 和 Group_C 都以 Group_A 中的所有内容开头,但之后有它们的元素,并且 Group_D 包含 Group_B 中的所有内容(本身又包括 Group_A 中的所有内容),然后添加自己的元素。

我希望这是声明性的,只是一堆数组数据声明,发生在编译时而不是运行时一堆数据结构构建代码。

这将被禁止递归,至少在实践中和运行时是这样。

是否有一个很好的、声明性的、看起来像数组的实现,或者我必须恢复到一些更复杂的动态数据结构实现,这些实现并不是在编译时以我喜欢的方式全部固定?

我的直觉是,某种标记的工会可能是唯一的出路。

struct pointer_or_doublepointer {
    int  which_kind;   // 0 == .element is valid; 1 == .table is valid
    union {
        real_type *  element; // valid only when which_kind == 0
        real_type ** table;   // valid only when which_kind == 1
    };
}

然后我会some_typepointer_or_doublepointer.

这真的是设置这样的东西的最佳方法,还是想到其他更好、更直接的解决方案?再次记住,这一切都应该通过数据声明来完成,而不是通过代码。

这是纯 C 语言,而不是 C++ 或其他变体。

4

2 回答 2

2

像这样的东西对你有用吗?

#define GROUPA elt0, elt1, elt2, elt3
#define GROUPB GROUPA, elt4, elt5
#define GROUPC GROUPA, elt6, elt7, elt8
#define GROUPD GROUPB, elt9, elt10, elt11

some_type group_A[] = {
    GROUPA, NULL
};

some_type group_B[] = {
    GROUPB, NULL
};

some_type group_C[] = {
    GROUPC, NULL
};

some_type group_D[] = {
    GROUPD, NULL
};

#undef GROUPA
#undef GROUPB
#undef GROUPC
#undef GROUPD

我认为这是使用宏来避免代码重复而不牺牲代码清晰度的完美案例。

于 2013-01-23T10:51:20.960 回答
1

由于您说对其他数组的引用只会出现在开头,因此表示这一点的一种简单方法是将此引用与其余元素分开保存:

struct ElementList {
    struct ElementList *prefix; //Reference to elements of another array, or NULL
    some_type *elements;        //additional elements
};

这比union解决方案更受限制,但可能更易于使用。

于 2013-01-23T10:45:13.167 回答