Ten kod jest przy użyciu kombinacji designated initializers i compound literals, które są zarówno C99 features, ja połączony do innych odpowiedzi, gdzie świadczenia standardowych ofert dla obu tych funkcji.
przeznaczona inicjalizatory pozwalają korzystać określić konkretne pole zainicjować za pomocą .fieldname =
, przykładem od połączonego dokumentu brzmi:
struct point { int x, y; };
następujące inicjalizacji
struct point p = { .y = yvalue, .x = xvalue };
jest równoważna
struct point p = { xvalue, yvalue };
Inną używaną funkcją są literały złożone, które są używane do tworzenia nienazwanych obiektów statycznych, a następnie kod pobiera adres tego obiektu i przypisuje mu odpowiednie wskaźniki left
i right
. Następnie używa tej funkcji rekursywnie w nienazwanych obiektach, aby ustawić odpowiednie wskaźniki.
.left = & (maze_t) { .... }
^^^^^^^^^^^^^^^^
unnamed static object
These bezimiennych obiektów są tylko statyczne, jeżeli są wykorzystywane poza ciałem funkcji w przeciwnym razie będą musieli automatyczny czas przechowywania i przestanie istnieć po wyjściu z funkcji, a więc biorąc ich adresy jak kod robi prawdopodobnie byłoby nierozsądne.
W celach informacyjnych podaję standardową ofertę na literały złożone w moim answer here.
Ważne, aby pamiętać, że podczas korzystania z wyznaczonych inicjatorów dowolne pole nie jawnie zainicjowana będzie initialized to zero, co jest rzeczywiście ważne w tym przypadku, na przykład hasCheese
zostanie ustawiony na 0
chyba że zostanie wyraźnie określone inaczej.
Chociaż są to C99 nie posiada wszystkie kompilatory obsługują lub w pełni wspierać C99 moje testy na Visual Studio pokazują, że konieczna jest wymiana pustych literały związku, na przykład:
left = &(maze_t) {}
z NULL
aby zmusić go do skompilować. Złożyłem numer bug report.
Odpowiedź do raportu o błędzie był następujący, ale w zasadzie jest to gcc/przedłużenie dzyń pracy:
Jest to rozszerzenie GNU. Clang obsługuje go jako rozszerzenie (zobacz opcję klang -Wgnu-empty-initializer).
Standardowy sposób zapisu to {0}, co spowoduje wyzerowanie wszystkich pól .
Przedstawiony kod opatrzony jest [post na blogu] (http://duartes.org/gustavo/blog/post/recursion/), w którym autor opisuje kod. –
Używają [literałów związków] (http://stackoverflow.com/questions/23294769/initialize-struct-without-an-assignment). –
'.left = & (maze_t) {};' i '.right = & (maze_t) {};' bardziej naturalnie zostaną zainicjowane na '0' lub' NULL'. W jego obecnym miejscu w hierarchii znajduje się dodatkowy element z wartością '.tag' równą 0 i wartością' .hasCheese' równą '0' (oraz zerowym lewym i prawym wskaźnikiem). –