1

次の(簡略化された)データ定義を使用します。

#define DIM0 10
#define DIM1 15

typedef struct {
    uint32_t var1:
    ...
    int8_t arrayVar1[DIM0];
 } dataClass0;

typedef struct {
    uint32_t var1:
    ...
    int8_t arrayVar1[DIM1];
 } dataClass1;

ある時点で、これらの構造の配列を作成して処理する必要があります。

処理は、配列(長さが異なる)を除いてまったく同じです。今のところ、次のようなものです。

 dataClass0 *data;
 data = (dataClass0 *) malloc(dimension * sizeof (dataClass0));
 // Processing and filling structure
 data[i].var1 = <value>
 ...

現在、データクラスごとに同じ関数を複製しています。これらのデータ構造を使用するときにコードを複製する方法はありますか?

ノート:

  • 純粋なCのみで、C++はありません。
  • データ定義を変更できません(つまりint8_t *arrayVar1、構造体で使用できません)。
  • 処理するときに、処理するデータのタイプを受け取ります(class0の場合は0、class1の場合は1 ...)。
4

3 に答える 3

3
typedef struct {
    uint32_t var1:
    ...
    int8_t arrayVar[];    /* Declare as flexible array, allowed since C99 */
} dataClass;

そのようなもので割り当てます:

data1 = malloc(sizeof (dataCLass) + DIM1*sizeof ((dataClass*)NULL)->arrayVar[0]);
data2 = malloc(sizeof (dataCLass) + DIM2*sizeof ((dataClass*)NULL)->arrayVar[0]);
or define
#define ALLOCDATA(dim) malloc(sizeof (dataCLass) + (dim)*sizeof ((dataClass*)NULL)->arrayVar[0]);

定義

#define ELEMENT1(data, i) (dataClass*)(((char*)(data))+(i)*(DIM1+sizeof (dataCLass)))
#define ELEMENT2(data, i) (dataClass*)(((char*)(data))+(i)*(DIM2+sizeof (dataCLass)))

または、DIMをパラメータ化する場合

#define ELEMENT(data, i, dim) (dataClass*)(((char*)(data))+(i)*((dim)+sizeof (dataCLass)))

楽しい

ELEMENT1(data1, i)->var1 = 1;
ELEMENT1(data1, i)->arrayVar1[9] = 4;


ELEMENT2(data2, i)->arrayVar1[14] = 4;

また

ELEMENT(data1, i, DIM1)->var1 = 1;
ELEMENT(data1, i, DIM1)->arrayVar1[9] = 4;


ELEMENT(data2, i, DIM2)->arrayVar1[14] = 4;

完璧ではありませんが、使用できないほど奇妙な構造ではありません。

編集:ELEMENT定義を次のように変更する必要があります

#define ELEMENT1(data, i) (dataClass*)(((char*)(data))+(i)*(DIM1*sizeof ((dataClass*)NULL)->arrayVar[0]+sizeof (dataCLass)))
#define ELEMENT2(data, i) (dataClass*)(((char*)(data))+(i)*(DIM2*sizeof ((dataClass*)NULL)->arrayVar[0]+sizeof (dataCLass)))

#define ELEMENT(data, i, dim) (dataClass*)(((char*)(data))+(i)*((dim)*sizeof ((dataClass*)NULL)->arrayVar[0]+sizeof (dataCLass)))

この変更により、arrayVarフィールドは任意のタイプにすることができ、サイズ1の要素に限定されません。

于 2013-03-27T12:42:07.230 に答える
1

アレイを動的にすることはできませんか?で構造を作成しmalloc()、サイズを保持するようにいくつかのメンバーを初期化するために(そしてuint8_t *、実際の配列の代わりに終了することを確認するか、VLAを使用します)?

于 2013-03-27T12:27:02.453 に答える
0

最初に配列に異なる値を入力するかどうかによって異なります。それ以外の場合は、両方のタイプの構造を初期化するマクロを作成できます

#define STRUCTURE_INITIALIZER(VAR1, VAR2) { .var1 = (VAR1), .var2 = (VAR2) }

そしてそれを

dataClass0 data = STRUCTURE_INITIALIZER(31, 42);

配列コンポーネントは0、サイズに関係なく、常に初期化されます。

mallocあなたのもののed配列を初期化するには:

dataClass0 *data  = malloc(dimension * sizeof (dataClass0));

// Processing and filling structure
for (size_t i = 0; i < dimension; ++i)
  data[i]= (dataClass0)STRUCTURE_INITIALIZER(43, i);

ところで、変数を適切に初期化することを好み、の戻り値をキャストしないでくださいmalloc

于 2013-03-27T13:00:44.560 に答える