4

私は、構造体の配列であるいくつかのデータ構造を宣言する方法を考え出そうとしています。ここで、後続の各配列は以前の配列の一部を使用します。重複を最小限に抑える方法。そうすれば、各要素は一度だけ宣言されます。

概念的には、これら 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_type、 の typedef を作成しますpointer_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 に答える