2013-06-22 9 views
9

W języku C zdefiniowałem strukturę widoczną poniżej i chciałbym ją zainicjować inline. (Ani pola wewnątrz struktury, ani tablica nie będą się zmieniać po inicjalizacji). Kod w pierwszym bloku działa dobrze.C - deklarowanie tablicy int wewnątrz struct

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

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

Jednak tak naprawdę nie potrzebuję pola tmp. W rzeczywistości po prostu zaśmieje mój kod (ten przykład jest nieco uproszczony). Zamiast tego chciałbym zadeklarować wartości some-array wewnątrz deklaracji dla foos. Nie mogę jednak uzyskać właściwej składni. Być może pole some-array powinno być zdefiniowane inaczej?

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

Musisz przydzielić pamięć dla * some_array używając funkcji malloc lub calloc. – user1929959

Odpowiedz

13
int *some_array; 

Tutaj some_array jest w rzeczywistości wskaźnik, a nie tablicą. Można określić ją tak:

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

Jeszcze jedno, cały sens typedef struct Foo Foo; jest użycie Foo zamiast struct Foo. I można go używać typedef tak:

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

Co więcej, wspominasz: "Pola wewnątrz struktury, ani zawartość tablicy nie ulegną zmianie po inicjalizacji", możesz więc przedrostać ich definicje prefiksem "const". na przykład 'const int element_array [3];'. Umożliwi to przypisanie, ale nie modyfikację. – kfsone

+0

@kfsone ITYM umożliwi inicjalizację, ale nie przypisanie lub modyfikację. –

20

Po pierwsze, istnieją 2 sposoby:

  • Wiesz rozmiar tej tablicy za
  • Nie znam tego rozmiaru.

W pierwszym przypadku jest to statyczna problemu programowania, a to nie jest skomplikowane:

#define Array_Size 3 

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

Możesz użyć tej składni, aby wypełnić tablicę:

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

kiedy nie znać rozmiar tablicy, jest to problem programowania dynamicznego. Musisz zapytać o rozmiar.

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 

drugie, typedef jest przydatna, więc kiedy piszesz tak:

typedef struct Foo { 
    ... 
} Foo; 

to znaczy, zastąpić "struct foo" rozmowę z tym: "foo". więc składnia będzie to:

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

Cheers.

+0

Tablica dynamiczna jest opisana całkiem dobrze w dokumentach GCC jednego z ich rozszerzeń: [tablice o długości zero] (https://gc.gnu.org/onlinedocs/gcc/Zero-Length.html). Możesz zadeklarować tablicę o długości zero jako ostatni element struktury i umieścić strukturę tuż przed rzeczywistą zawartością tablicy w pamięci. Zauważ, że jest to tylko rozszerzenie i standardowe sposoby osiągnięcia tego samego są tam również opisane. – Palec

1

Moja odpowiedź jest dla następujących sekcji kodu: -

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

wszystkich powyższych kwestii kompilacji ze względu na to nie jest zgodne z normami ANSI, łączna „foos” jest mający subaggregates z których niektóre są w nawiasie, podczas gdy inne nie. Jeśli więc usuniesz nawiasy wewnętrzne do , reprezentujesz tablicę "tmp", skompilowałbyś ją bezbłędnie. Na przykład

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