3

2 種類のオブジェクトの構造体を定義する必要があります。どちらもまったく同じデータ構造を持ち、同じタスク (メンバー メソッド) を実行します。

唯一の違いは、配列サイズが 2 つのタイプで異なることです。1 つは SIZE_A を使用し、もう 1 つは 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

ユニオンを使用しても、構造体は 2 つの配列の最大のものと同じ大きさになります。

次のいずれかを実行します。

  1. 最大配列サイズのオーバーヘッドを無視します。(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])

iしたがって、 の番目の行とj番目の列、および のs *foo番目の要素にアクセスするには:matrkarr

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 プログラマーは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.89-90 では、matrより大きな値で配列にインデックスを付けると、0技術的にその境界を越えてオブジェクトにアクセスするため、これはハックです。ただし、これは一般的な方法であり、広く移植可能でした。C.99 では、柔軟な配列メンバーを使用してメカニズムを正式に認可しましたが、配列宣言でサイズを指定しないという構文が必要です。

于 2013-07-30T23:13:27.107 に答える
1

配列をポインターにして、必要に応じて (適切なサイズで) 割り当てます。ダウンサイズだけは、2D 配列へのアクセスが少しぎこちなくなります。

于 2013-07-30T20:28:06.160 に答える