web-dev-qa-db-ja.com

構造体内のint配列を宣言する

Cでは、以下に示すstructを定義しており、インラインで初期化したいと思います。構造体内のフィールドも配列foosも初期化後に変更されません。最初のブロックのコードは正常に機能します。

struct Foo {
  int bar;
  int *some_array;
};

typedef struct Foo Foo;

int tmp[] = {11, 22, 33};
struct Foo foos[] = { {123, tmp} };

ただし、tmpフィールドは実際には必要ありません。実際、コードが乱雑になります(この例は多少簡略化されています)。そのため、代わりにfoosの宣言内でsome_arrayの値を宣言したいと思います。ただし、正しい構文を取得できません。フィールドsome_arrayは別の方法で定義する必要がありますか?

int tmp[] = {11, 22, 33};
struct Foo foos[] = {
  {123, tmp},                    // works
  {222, {11, 22, 33}},           // doesn't compile
  {222, new int[]{11, 22, 33}},  // doesn't compile
  {222, (int*){11, 22, 33}},     // doesn't compile
  {222, (int[]){11, 22, 33}},    // compiles, wrong values in array
};
16
Bob
int *some_array;

ここで、some_arrayは実際には配列ではなくポインタです。次のように定義できます。

struct Foo {
  int bar;
  int some_array[3];
};

もう1つ、typedef struct Foo Foo;のポイントは、struct Fooの代わりにFooを使用することです。そして、次のようにtypedefを使用できます。

typedef struct Foo {
  int bar;
  int some_array[3];
} Foo;
16
Yu Hao

まず、2つの方法があります。

  • あなたはその配列のサイズを知っています
  • あなたはそのサイズを知りません。

最初のケースでは、静的プログラミングの問題であり、複雑ではありません。

#define Array_Size 3

struct Foo {
    int bar;
    int some_array[Array_Size];
};

この構文を使用して、配列を埋めることができます。

struct Foo foo;
foo.some_array[0] = 12;
foo.some_array[1] = 23;
foo.some_array[2] = 46;

配列のサイズがわからない場合は、動的プログラミングの問題です。サイズを尋ねる必要があります。

struct Foo {

   int bar;
   int array_size;
   int* some_array;
};


struct Foo foo;
printf("What's the array's size? ");
scanf("%d", &foo.array_size);
//then you have to allocate memory for that, using <stdlib.h>

foo.some_array = (int*)malloc(sizeof(int) * foo.array_size);
//now you can fill the array with the same syntax as before.
//when you no longer need to use the array you have to free the 
//allocated memory block.

free( foo.some_array );
foo.some_array = 0;     //optional

第二に、typedefは便利なので、これを書くとき:

typedef struct Foo {
   ...
} Foo;

つまり、「struct Foo」の単語を「Foo」に置き換えます。したがって、構文は次のようになります。

Foo foo;   //instead of "struct Foo foo;

乾杯。

26
Bertie92

私の答えは、次のコードセクションです:-

int tmp[] = {11, 22, 33};
struct Foo foos[] = {
  {123, tmp},   // works
  {222, {11, 22, 33}},  // doesn't compile
  {222, new int[]{11, 22, 33}},  // doesn't compile
  {222, (int*){11, 22, 33}},  // doesn't compile
  {222, (int[]){11, 22, 33}},  // compiles, wrong values in array
};

上記のコンパイルの問題はすべて、ANSI標準との互換性がないためです。集計「foos」には、サブ集計があり、その一部は括弧で囲まれていますが、その他はそうではありません。したがって、配列 'tmp'を表すために内部ブラケットを削除すると、必ずコンパイルされます。例えば.

struct Foo foos[] = {
  {123, tmp},   // works
  {222,  11,22,33 },  // would compile perfectly.
}
2
smitha