DODATEK A PRZEWODNIK JĘZYKA C
Struktury i tablice są obiektami złożonymi. Jeśli obiekt złożony zawiera składowe złożonego typu, to zasady inicjowania odnoszą się rekurencyjnie do tych składowych. Następujące zasady regulują stosowanie nawiasów klamrowych przy inicjowaniu. Jeśli inicjator dla składowej obiektu złożonego, która sama jest obiektem złożonym, rozpoczyna się lewą klamrą, to następująca po klamrze lista inicjatorów rozdzielonych przecinkami określa wartości początkowe składowych tej składowej; jest błędem, gdy inicjatorów jest więcej niż jej składowych. Jeżeli natomiast inicjator dla złożonej składowej nie rozpoczyna się klamrą, to z listy bierze się tylko tyle inicjatorów, ile jest wymaganych dla tej składowej. Pozostałe elementy listy służą do zainicjowania następnej składowej obiektu złożonego.
Oto przykłady:
int x[] = { 1,3,5};
Ponieważ nie podano wymiaru, a lista inicjatorów zawiera trzy elementy, wiersz ten deklaruje i inicjuje zmienną X jako jednowymiarową tablicę o trzech elementach.
float y[4j[3] = {
{ 1.3,5},
{ 2, 4, 6 },
{ 3, 5, 7 },
To inicjowanie jest całkowicie „sklamrowane”: 1,3 i 5 inicjują pierwszy wiersz tablicy y[0], tzn. elementy y[0][01, y[0][1] i y[0][2]. Podobnie następne wartości inicjują wiersze y[1j i y[2|. Inicjator kończy się za wcześnie, zatem elementy wiersza y[3] zostaną zainicjowane zerami. Ten sam efekt można osiągnąć pisząc
float y[4][3] = {
1,3, 5, 2, 4, 6, 3, 5,7
Inicjator dla y rozpoczyna się lewą klamrą, ale już dla y[0] nie - z listy zostaną więc pobrane trzy początkowe elementy. Podobnie, następne porcje po trzy elementy będą pobierane kolejno dla y[1] i y[2]. Natomiast
float y[4][3] = {
{1 }. (2}, {3},{4}
inicjuje tylko pierwszą kolumnę tablicy y (dwuwymiarowej), pozostałe elementy wypełniając zerami.
A8 DEKLARACJE
Na koniec deklaracja
char msg[] = ”Błąd składniowy w wierszu %s\n”;
wprowadza tablicę znakową, której elementy są inicjowane napisem; w jej rozmiarze uwzględnia się zerowy znak kończący napis.
podanie nazwy typu danych jest konieczne w kilku przypadkach: przy wymuszaniu przekształcenia typu przez rzutowanie, przy zadeklarowaniu typów parametrów w de-klaratorze funkcji oraz w argumencie operatora sizeof. Do tego celu służy nazwa-ty-pu, która w składni pełni rolę deklaracji obiektu żądanego typu z pominiętą nazwą obiektu.
nazwa-typu:
lista-spec-kwal deklarator-abstrakcyjnyopc
dekla rato r-abstrakcyjny: wskaźnik
wskaźnik,,pc bezp-deklarator-abstrakcyjny
bezp-deklarator-abstrakcyjny:
( deklarator-abstrakcyjny )
bezp-deklarator-abstrakcyjny „pc [ wyrazenie-stałe,w ] bezp-deklarator-abstrakcyjny„pc ( Usta-typów-parametrów„pc )
W deklaratorze abstrakcyjnym można jednoznacznie określić miejsce, w którym mógłby wystąpić identyfikator, gdyby taka konstrukcja była deklaratorem w deklaracji. Nazwany typ jest więc identyczny z typem domniemanego identyfikatora. Na przykład nazwy typów:
int int * int *[3] int (*)[] int *()
int (*[]) (void)
°znaczają odpowiednio: „typ całkowity”, „wskaźnik do obiektów całkowitych”, „tablica złożona z trzech wskaźników do elementów całkowitych”, „wskaźnik do tablicy
I
293