DODATEK A PRZEWODNIK JĘZYKA C
W pierwszym wydaniu książki typ wyrażenia przyrostkowego był ograniczony do „funkcji”; przy wywołaniu funkcji za pomocą wskaźnika należało jawnie stosować operator *. Standard ANSI „udziela błogosławieństwa” praktykom stosowanym przez niektóre kompilatory, zezwalając na tę samą składnię przy wywołaniu funkcji i wywołaniu funkcji za pomocą wskaźnika. Starsza składnia nadal może być stosowana.
Pojęcie argument oznacza wyrażenie przekazane przez wywołanie funkcji; pojęcie parametr oznacza wejściowy obiekt (lub jego identyfikator) otrzymany przez definicję funkcji lub opisany w deklaracji funkcji. To samo rozróżnienie formułuje się niekiedy stosując pojęcia, odpowiednio, „argument (parametr) aktualny” i „argument (parametr) formalny”.
Podczas obsługi wywołania funkcji tworzy się kopie wszystkich argumentów; argumenty są przekazywane wyłącznie przez wartość. Funkcja może zmienić wartości swoich parametrów, które są kopiami argumentów, ale nie ma to wpływu na wartości faktycznych argumentów. Można natomiast przekazać funkcji wskaźnik, godząc się z tym, że funkcja może zmienić wartość wskazywanego obiektu.
Dopuszcza się dwa style deklaracji funkcji - stary i nowy. W nowym stylu typy parametrów są jawne i są częścią typu funkcji - taka deklaracja nazywa się prototypem funkcji. Deklaracja w starym stylu nie zawiera typów parametrów. Opis deklaracji funkcji znajduje się w p. A8.6.3 i A 10.1.
Jeśli w zasięgu wywołania funkcji obowiązuje stary styl deklaracji funkcji, to stosuje się domyślną promocję typów argumentów wywołania: dla argumentów całkowitych stosuje się promocję typu całkowitego (p. A6.1), argumenty typu float przekształca się do double. Skutek wywołania funkcji nie jest zdefiniowany, jeśli liczba argumentów nie zgadza się z liczbą parametrów w definicji funkcji lub jeśli typ jakiegoś argumentu po zastosowaniu promocji nie zgadza się z typem odpowiedniego parametru. Zgodność typów zależy od tego, czy funkcja była zdefiniowana w nowym stylu czy w starym. Jeśli definicja funkcji jest w starym stylu, to porównanie zachodzi między promowanym typem argumentu wywołania a promowanym typem parametru. Jeśli definicja jest w nowym stylu, to promowany typ argumentu musi być taki sam, jak typ parametru bez promocji.
Jeśli w zasięgu wywołania funkcji obowiązuje nowy styl deklaracji funkcji, to argumenty są przekształcane (jak w przypisaniu) do typów odpowiednich parametrów prototypu funkcji. Liczba argumentów musi się równać liczbie jawnie podanych parametrów, chyba że listę parametrów w deklaracji kończy wielokropek (, ...). W tym przypadku liczba argumentów musi być nie mniejsza niż liczba parametrów; nadliczbowe argumenty (w stosunku do jawnie wyszczególnionych parametrów) podlegają domyślnej promocji typu, tak jak to zostało opisane w poprzednim akapicie. Jeśli definicja funkcji jest w starym stylu, to wszystkie parametry prototypu funkcji znajdującego się
A7 WYRAŻENIA
po we red by
w zasięgu wywołania muszą się zgadzać z odpowiednimi parametrami cji (po zastosowaniu promocji typów do parametrów definicji).
Te reguły są wyjątkowo skomplikowane, muszą się one bowiem stosować do mieszaniny funkcji w nowym i starym stylu. Jeśli to tylko możliwe, takiej mieszaniny należy się wystrzegać.
Kolejność obliczania argumentów nie jest zdefiniowana; należy pamiętać o tym, że poszczególne kompilatory postępują różnie. Pewne jest natomiast, że zanim funkcja rozpocznie działanie, argumenty i oznacznik funkcji są już całkowicie obliczone, włączając w to wszystkie efekty uboczne. Każdą funkcję można wywoływać rekurencyjnie.
Wyrażenie przyrostkowe, po którym następuje kropka i identyfikator, jest wyrażeniem przyrostkowym. Pierwsze wyrażenie musi być strukturą lub unią, a identyfikator - nazwą składowej tej struktury lub unii. Wynikiem jest wskazana składowa, a typem - typ tej składowej. Wyrażenie to jest 1-wartością, jeżeli pierwsze wyrażenie jest 1-wartością, a składowa nie jest tablicą.
Wyrażenie przyrostkowe, po którym następuje strzałka (złożona ze znaków - i >) oraz identyfikator, jest wyrażeniem przyrostkowym. Pierwsze wyrażenie musi być wskaźnikiem do struktury lub unii, a identyfikator musi być nazwą składowej tej struktury lub unii. Wynikiem jest składowa struktury lub unii wskazanej przez wyrażenie wskaźnikowe, a jego typem - typ tej składowej; wynik jest 1-wartością, jeśli typ ten nie jest typem tablicowym.
Zatem wyrażenie E1->MOS jest tym samym, co (*E1).MOS. Struktury i unie są opisane w p. A8.3.
Już w pierwszym wydaniu książki było regułą, że nazwa składowej w takim wyrażeniu musiała należeć do struktury lub unii określonej wyrażeniem przyrostkowym; zaznaczono jednak, że reguła ta nie była zbyt rygorystycznie przestrzegana. Nowe kompilatory, również ANSI, przestrzegają jej.
Wyrażenie przyrostkowe, po którym następuje operator ++ lub —, jest wyrażeniem Przyrostkowym. Wartością wyrażenia jest wartość argumentu. Po obliczeniu wartości argument jest zwiększany (++) lub zmniejszany (—) o jeden. Argument musi być ^Wartością; dalsze wymagania w stosunku do argumentu oraz szczegóły operacji są
267