C Language
Literały złożone
Szukaj…
Składnia
- (type) {initializer-list}
Uwagi
Norma C mówi w C11-§6.5.2.5 / 3:
Wyrażenie postfiksowe, które składa się z nazwy typu w nawiasach, po której znajduje się lista inicjatorów w nawiasach klamrowych, jest literałem złożonym . Zapewnia nienazwany obiekt, którego wartość jest podawana przez listę inicjalizującą. 99)
a przypis 99 mówi:
Zauważ, że różni się to od wyrażenia rzutowanego. Na przykład rzutowanie określa konwersję na typy skalarne lub tylko puste , a wynik wyrażenia rzutowania nie jest wartością.
Uwaga:
Literały łańcuchowe i literały złożone z typami stałymi, nie muszą oznaczać odrębnych obiektów. 101)
101) Umożliwia to implementacjom współdzielenie pamięci dla literałów łańcuchowych i stałych literałów złożonych z tymi samymi lub nakładającymi się reprezentacjami.
Przykład podano w standardzie:
C11-§6.5.2.5 / 13:
Podobnie jak literały łańcuchowe, stałe literały złożone mogą być umieszczone w pamięci tylko do odczytu, a nawet mogą być współużytkowane. Na przykład,
(const char []){"abc"} == "abc"
może dać 1, jeśli pamięć literałów jest współdzielona.
Definicja / Inicjalizacja literałów złożonych
Złożony literał to nienazwany obiekt, który jest tworzony w zakresie, w którym został zdefiniowany. Koncepcja została po raz pierwszy wprowadzona w standardzie C99. Przykładem literału złożonego jest
Przykłady ze standardu C, C11-§6.5.2.5 / 9:
int *p = (int [2]){ 2, 4 };
p
jest inicjowany na adres pierwszego elementu nienazwanej tablicy dwóch liczb całkowitych.
Złożony literał jest wartością. Czas przechowywania nienazwanego obiektu jest albo statyczny (jeśli literał pojawia się w zakresie pliku), albo automatyczny (jeśli literał pojawia się w zakresie bloku), aw tym drugim przypadku czas życia obiektu kończy się, gdy kontrola opuszcza otaczający blok.
void f(void) { int *p; /*...*/ p = (int [2]){ *p }; /*...*/ }
p
jest przypisany adres pierwszego elementu tablicy dwóch liczb całkowitych, z których pierwszy ma wartość wskazywaną wcześniej przezp
a drugi zero. [...]
Tutaj p
pozostaje ważne do końca bloku.
Złóż literał z desygnatorami
(również z C11)
struct point {
unsigned x;
unsigned y;
};
extern void drawline(struct point, struct point);
// used somewhere like this
drawline((struct point){.x=1, .y=1}, (struct point){.x=3, .y=4});
drawline
funkcja drawline
otrzymuje dwa argumenty typu struct point
. Pierwszy ma wartości współrzędnych x == 1
i y == 1
, podczas gdy drugi ma x == 3
i y == 4
Złóż literał bez określania długości tablicy
int *p = (int []){ 1, 2, 3};
W takim przypadku rozmiar tablicy nie jest określony, a następnie zostanie określony na podstawie długości inicjalizatora.
Złożony literał mający długość inicjatora mniejszą niż określony rozmiar tablicy
int *p = (int [10]){1, 2, 3};
pozostałe elementy literału złożonego zostaną domyślnie zainicjowane na 0
.
Literał złożony tylko do odczytu
Zauważ, że literał złożony jest wartością i dlatego jego elementy można modyfikować. Literał złożony tylko do odczytu można określić za pomocą kwalifikatora const
jako (const int[]){1,2}
.
Złożony literał zawierający dowolne wyrażenia
Wewnątrz funkcji literał złożony, jak w przypadku każdej inicjalizacji od C99, może mieć dowolne wyrażenia.
void foo()
{
int *p;
int i = 2; j = 5;
/*...*/
p = (int [2]){ i+j, i*j };
/*...*/
}