web-dev-qa-db-fra.com

Déclarer un tableau int à l'intérieur d'une structure

En C, j'ai défini le struct vu ci-dessous, et je voudrais l'initialiser en ligne. Ni les champs à l'intérieur de la structure, ni le tableau foos ne changeront après l'initialisation. Le code du premier bloc fonctionne correctement.

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

typedef struct Foo Foo;

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

Cependant, je n'ai pas vraiment besoin du champ tmp. En fait, cela ne fera qu'encombrer mon code (cet exemple est quelque peu simplifié). Donc, je voudrais plutôt déclarer les valeurs de some_array à l'intérieur de la déclaration pour foos. Cependant, je ne peux pas obtenir la bonne syntaxe. Peut-être que le champ some_array devrait être défini différemment?

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;

Ici, some_array est en fait un pointeur, pas un tableau. Vous pouvez le définir comme ceci:

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

Encore une chose, tout l'intérêt de typedef struct Foo Foo; consiste à utiliser Foo au lieu de struct Foo. Et vous pouvez utiliser typedef comme ceci:

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

Tout d'abord, il y a 2 façons:

  • Vous savez la taille de ce tableau
  • Vous ne connaissez pas cette taille.

Dans le premier cas, c'est un problème de programmation statique, et ce n'est pas compliqué:

#define Array_Size 3

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

Vous pouvez utiliser cette syntaxe pour remplir le tableau:

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

Lorsque vous ne connaissez pas la taille du tableau, c'est un problème de programmation dynamique. Vous devez demander la taille.

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

Deuxièmement, typedef est utile, donc lorsque vous écrivez ceci:

typedef struct Foo {
   ...
} Foo;

cela signifie que vous remplacez les mots "struct Foo" par ceci: "Foo". La syntaxe sera donc la suivante:

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

À votre santé.

26
Bertie92

Ma réponse est pour la section de code suivante: -

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
};

Tous les problèmes de compilation ci-dessus sont dus au fait qu'il n'est pas compatible avec les normes ANSI, les "foos" d'agrégats ont des sous-agrégats dont certains sont entre crochets tandis que d'autres ne le sont pas. Donc, si vous supprimez les crochets internes pour représenter le tableau "tmp", il sera compilé sans échec. Par exemple.

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