Chcę zainicjować element struct, podzielić na deklarację i inicjalizację. Oto co mam:
typedef struct MY_TYPE {
bool flag;
short int value;
double stuff;
} MY_TYPE;
void function(void) {
MY_TYPE a;
...
a = { true, 15, 0.123 }
}
Czy to jest sposób na zadeklarowanie i zainicjowanie zmiennej lokalnej MY_TYPE
zgodnie ze standardami języka programowania C (C89, C90, C99, C11 itd.)? A może jest coś lepszego lub przynajmniej działa?
Aktualizacja Skończyłem z statycznym elementem inicjującym, w którym ustawiam każdy podelement zgodnie z moimi potrzebami.
c
struct
initialization
żenada
źródło
źródło
Odpowiedzi:
W (ANSI) C99 możesz użyć wyznaczonego inicjatora do zainicjowania struktury:
Edycja: Inne elementy są inicjowane jako zero: „Pominięte elementy pola są domyślnie inicjowane tak samo jak obiekty o statycznym czasie przechowywania.” ( https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html )
źródło
Możesz to zrobić za pomocą złożonego literału . Według tej strony działa w C99 (który również liczy się jako ANSI C ).
Oznaczenia w inicjalizatorach są opcjonalne; możesz także napisać:
źródło
Widzę, że już otrzymałeś odpowiedź na temat ANSI C 99, więc rzucę kość o ANSI C 89. ANSI C 89 pozwala na zainicjowanie struktury w ten sposób:
Ważną rzeczą do zapamiętania, w momencie inicjalizacji choćby jednego obiektu / zmiennej w strukturze, wszystkie pozostałe zmienne zostaną zainicjalizowane do wartości domyślnej.
Jeśli nie zainicjujesz wartości w swojej strukturze, wszystkie zmienne będą zawierały „wartości śmieci”.
Powodzenia!
źródło
a = (MYTYPE){ true, 15, 0.123 };
sprawdziłby się w C99
źródło
Już prawie masz ...
Szybkie wyszukiwanie w „struct initialize c” pokazuje mi to
źródło
Norma języka programowania C ISO / IEC 9899: 1999 (powszechnie znana jako C99) pozwala na użycie wyznaczonego inicjatora do inicjowania elementów struktury lub unii w następujący sposób:
Jest zdefiniowany w
paragraph 7
sekcji6.7.8 Initialization
normy ISO / IEC 9899: 1999 jako:Należy zauważyć, że
paragraph 9
w tej samej sekcji stwierdzono, że:Jednak w implementacji GNU GCC pominięte elementy są inicjowane jako wartość odpowiednia dla typu zero lub podobna do zera. Jak stwierdzono w sekcji 6.27 Wyznaczone inicjatory dokumentacji GNU GCC:
Kompilator Microsoft Visual C ++ powinien obsługiwać wyznaczone inicjatory od wersji 2013, zgodnie z oficjalnym blogiem C ++ Conformance Roadmap . Akapit artykułu
Initializing unions and structs
o inicjalizatorach w dokumentacji MSDN Visual Studio sugeruje, że nienazwani członkowie inicjują się do odpowiednich zerowych wartości, podobnie jak GNU GCC.Norma ISO / IEC 9899: 2011 (powszechnie znana jako C11), która zastąpiła normę ISO / IEC 9899: 1999, zachowuje wyznaczone inicjatory zgodnie z sekcją
6.7.9 Initialization
. Zachowuje równieżparagraph 9
niezmienione.Nowa norma ISO / IEC 9899: 2018 (powszechnie znana jako C18), która zastąpiła ISO / IEC 9899: 2011, zachowuje wyznaczone inicjatory w sekcji
6.7.9 Initialization
. Zachowuje równieżparagraph 9
niezmienione.źródło
struct thing { union { char ch; int i; }; };
. Później standard mówi: „Jeśli na liście zamkniętej nawiasami znajduje się mniej inicjatorów, niż elementów lub elementów agregujących, lub mniej liter w łańcuchu znaków używanych do inicjalizacji tablicy o znanym rozmiarze, niż elementów w tablicy, pozostałą część agregatu inicjuje się domyślnie tak samo jak obiekty o statycznym czasie przechowywania. ”jak powiedział Ron Nuni:
Ważną rzecz do zapamiętania: w momencie inicjalizacji nawet jednego obiektu / zmiennej w strukturze, wszystkie pozostałe zmienne zostaną zainicjalizowane do wartości domyślnej.
Jeśli nie zainicjujesz wartości w swojej strukturze (tj. Jeśli po prostu zadeklarujesz tę zmienną), wszystkie
variable.members
będą zawierały „wartości śmieci”, tylko jeśli deklaracja jest lokalna!Jeśli deklaracja jest globalna lub statyczna (jak w tym przypadku), wszystkie niezainicjowane
variable.members
zostaną automatycznie zainicjowane, aby:0
dla liczb całkowitych i zmiennoprzecinkowych'\0'
dlachar
(oczywiście jest to tak samo jak0
ichar
jest liczbą całkowitą)NULL
dla wskaźników.źródło
źródło
Jeśli MS nie zaktualizowało się do C99, MY_TYPE a = {true, 15,0.123};
źródło
Znalazłem inny sposób inicjowania struktur.
Struktura:
Inicjalizacja:
Zgodnie z dokumentacją GCC ta składnia jest przestarzała od GCC 2.5 .
źródło
Nie podobała mi się żadna z tych odpowiedzi, więc zrobiłem własną. Nie wiem, czy to ANSI C, czy nie, to tylko GCC 4.2.1 w trybie domyślnym. Nigdy nie pamiętam braketingu, więc zaczynam od podzbioru moich danych i walczę z komunikatami o błędach kompilatora, dopóki się nie zamknie. Czytelność jest moim pierwszym priorytetem.
Dane mogą rozpoczynać życie jako plik rozdzielany tabulatorami, który należy przeszukiwać i zamieniać w coś innego. Tak, to są rzeczy Debiana. Tak więc jedna zewnętrzna para {} (wskazująca tablicę), a następnie kolejna para dla każdej struktury wewnątrz. Z przecinkami między. Umieszczanie rzeczy w nagłówku nie jest absolutnie konieczne, ale mam około 50 elementów w mojej strukturze, więc chcę je w osobnym pliku, zarówno po to, aby nie bałagan w moim kodzie, więc łatwiej jest go zamienić.
źródło
Strukturę w C można zadeklarować i zainicjować w następujący sposób:
źródło
Przeczytałem już dokumentację Microsoft Visual Studio 2015 dotyczącą inicjowania typów agregatów , wszystkie formy inicjowania
{...}
są tam wyjaśnione, ale nie ma tam mowy o inicjowaniu za pomocą kropki o nazwie „desygnator”. To też nie działa.Standardowy C99 rozdział 6.7.8 Inicjalizacja wyjaśnia możliwości desygnatorów, ale moim zdaniem nie jest tak naprawdę jasne dla złożonych struktur. Standard C99 jako pdf .
Moim zdaniem może być lepiej
= {0};
-inicjalizacji dla wszystkich danych statycznych. Kod maszynowy wymaga mniej wysiłku.Na przykład użyj makr do inicjalizacji
typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}
Makro można dostosować, jego lista argumentów może być niezależna od zmienionej zawartości struktury. Właściwe jest, aby zainicjować mniej elementów. Jest także odpowiedni dla zagnieżdżonej struktury. 3. Prosty formularz to: Zainicjuj w podprogramie:
Ta procedura wygląda jak ObjectOriented w C. Użyj
thiz
, niethis
kompiluj jej również w C ++!źródło
Szukałem fajnego sposobu na zainicjowanie mojej struktury i muszę skorzystać z poniższego (C99). To pozwala mi zainicjować pojedynczą strukturę lub tablicę struktur w taki sam sposób, jak zwykłe typy.
Można to wykorzystać w kodzie jako:
źródło
jsmn_ts_default
, ale pozostałe struktury są inicjowane tak, jakby tablica miała statyczny czas przechowywania, co oznacza, że elementy są inicjowane doNULL
i0
. Ale jeśli#define jsmn_ts_default (jsmn_ts){"default", sizeof "default", NULL, 0}
przejdziesz na to, zobaczysz, że tylko pierwszy element tablicy zostanie tak zainicjowany.int a[10] = {1};
Tylko pierwszy element będzie==1