2013-06-22 23 views
9

In C, ho definito la struttura vista di seguito e vorrei inizializzarla in linea. (Né i campi all'interno della struttura né l'array foos cambieranno dopo l'inizializzazione). Il codice nel primo blocco funziona correttamente.C - dichiarazione int array all'interno struct

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

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

Tuttavia, non ho davvero bisogno del campo tmp. In effetti, ingombra solo il mio codice (questo esempio è in qualche modo semplificato). Quindi, invece, vorrei dichiarare i valori di some-array all'interno della dichiarazione per foos. Non riesco a ottenere la sintassi corretta, però. Forse il campo some-array dovrebbe essere definito in modo diverso?

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

È necessario allocare spazio di memoria per * some_array utilizzando le funzioni malloc o calloc. – user1929959

risposta

13
int *some_array; 

Qui, some_array è in realtà un puntatore, non un array. Si può definire così:

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

più una cosa, il punto di typedef struct Foo Foo; è quello di utilizzare al posto di Foostruct Foo. Ed è possibile utilizzare typedef come questo:

typedef struct Foo { 
    int bar; 
    int some_array[3]; 
} Foo; 
+1

Inoltre, si cita "I campi all'interno della struttura, né gli schieramenti dell'array cambieranno dopo l'inizializzazione", quindi è possibile anteporre le proprie definizioni al prefisso "const". per esempio. 'const int some_array [3];'. Ciò consentirà l'assegnazione ma non la modifica. – kfsone

+0

@kfsone ITYM consentirà l'inizializzazione ma non l'assegnazione o la modifica –

20

In primo luogo, ci sono 2 modi:

  • Sai dimensione che dell'array
  • Tu non sai quel formato.

Nel primo caso si tratta di un problema di programmazione statica, e non è complicato:

#define Array_Size 3 

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

È possibile utilizzare questa sintassi per compilare la matrice:

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

Quando non conoscere le dimensioni dell'array, è un problema di programmazione dinamica. Devi chiedere la taglia.

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 

In secondo luogo, typedef è utile, in modo che il quando si scrive questo:

typedef struct Foo { 
    ... 
} Foo; 

significa sostituire le parole "struct Foo" con questo: "Foo". Così la sintassi sarà questo:

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

Cin cin.

+0

L'array dinamico è descritto abbastanza bene nei documenti GCC di una delle loro estensioni: [array di lunghezza zero] (https://gcc.gnu.org/onlinedocs/gcc /Zero-Length.html). È possibile dichiarare una matrice di lunghezza zero come ultimo membro di una struct e posizionare la struct proprio prima dei contenuti dell'array effettivo nella memoria. Si noti che è solo un'estensione e sono descritti anche i modi standard per ottenere lo stesso. – Palec

1

La mia risposta è la seguente sezione di codice: -

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

Tutte le emissioni di compilazione di cui sopra è a causa di essa non è compatibile con gli standard ANSI, l'aggregato 'foos' sta avendo subaggregates alcune delle quali sono messo tra parentesi mentre altri no. Quindi se rimuovi le parentesi interne su rappresenta l'array 'tmp' si compilerebbe senza errori. Per es.

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