ANSI C 0

ANSI C 0



2 TYPY, OPERATORY I WYRAŻENIA

struktury; będą szczegółowo opisane w rozdz. 6 razem z operatorem sizeof (rozmiar obiektu). W rozdziale 5 poznamy jednoargumentowe operatory * (dostęp pośredni za pomocą wskaźnika) oraz & (adres obiektu), a w rozdz. 3 zapoznamy się z operatorem! , (przecinek).

Zauważ, że priorytet bitowych operatorów &, oraz | jest niższy niż priorytet operatorów przyrównania == i !=. Wynika z tego, że wyrażenia testujące bity, np.

if ((x & MASK) == 0) ...

aby dawały poprawne wyniki, muszą zawierać odpowiednią liczbę nawiasów.

Tablica 2-1. Priorytety i łączność operatorów

Operatory

Łączność

o n -> ■

lewostrona

! ~ -H- — + - * & (typ) sizeof

prawostronna

* / %

lewostronna

+ -

lewostronna

« »

lewostronna

<<=>>=

lewostronna

== !=

lewostronna

&

lewostronna

lewostronna

i

lewostronna

&&

lewostronna

ii

lewostronna

?• • •

prawostronna

= += -= *= /= %= ~ = |= «= »=

prawostronna

lewostronna

Jednoargumentowe operatory +,    * oraz & mają priorytet wyższy niż ich odpowiedniki

dwuargumentowe.

W języku C, jak w większości języków programowania, nie określa się kolejności o*| liczania wartości argumentów operatora. (Do wyjątków należą operatory &&, ||, oraz ’,’.) Na przykład w instrukcji

x = f() + g 0;    1

funkcja f może być wykonana przed funkcją g lub odwrotnie. A więc w przypadł gdy jedna z funkcji (f lub g)zmienia wartość zmiennej, od której zależy ta druga, w* tość zmiennej X może zależeć od kolejności wykonania tych funkcji. Aby zapewfl

Operator jest lewostronnie (prawostronnie) łączny, jeżeli w wyrażeniu zawierającym co najmniej dwa operatory na tym samym poziomie struktury nawiasowej najpierw jest wykonywany operator lewy (pra^ Operator jest łączny, jeżeli kolejność wykonywania jest dowolna. - Przyp. tłum.

2.12 PRIORYTETY I KOLEJNOŚĆ OBLICZEŃ

powered oy


szczególną kolejność obliczeń, wyniki pośrednie można przechowywać w zmiennych tymczasowych.

Podobnie kolejność obliczania wartości argumentów funkcji nic jest określona, toteż instrukcja

printf(”%d %d\n”, -h-n, power(2,n)); /* ŹLE */

może dla różnych kompilatorów produkować różne wyniki zależnie od tego, czy n jest zwiększane przed czy po wywołaniu funkcji power. Rozwiązaniem jest oczywiście napisanie programu inaczej, np.

++n;

printf(”%d %d\n‘\ n, power(2,n));

Wywołania funkcji, zagnieżdżone instrukcje przypisania oraz operatory zwiększania i zmniejszania powodują „efekty uboczne” - przy okazji obliczania wyrażenia pewna zmienna otrzymuje nową wartość. W wyrażeniu powodującym efekty uboczne może pojawić się subtelna zależność od kolejności aktualizacji wartości zmiennych biorących udział w obliczeniach. Ilustracją takiej niefortunnej sytuacji jest instrukcja

a[i] = i++;

Pytanie brzmi: czy indeks tej tablicy jest starą wartością i czy nową? Kompilatory mogą przetłumaczyć tę instrukcję na wiele sposobów i wygenerować różne odpowiedzi według własnej interpretacji. W standardzie specjalnie nic uściślano tego rodzaju spraw. To, kiedy w wyrażeniu nastąpi efekt uboczny (przypisanie wartości zmiennej), pozostawia się decyzji kompilatora, ponieważ najlepsza kolejność obliczeń ściśle zależy od architektury maszyny. (Jednocześnie w standardzie stwierdzono, że wszystkie efekty uboczne obliczenia argumentów funkcji muszą mieć miejsce przed jej wywołaniem, ale to niewiele pomaga w powyższym wywołaniu funkcji printf.)

Morał z tej dyskusji jest następujący: pisanie programów zależnych od kolejności wykonywania obliczeń należy do złej praktyki programowania w każdym języku. Naturalnie trzeba wiedzieć, czego unikać, lecz jeśli nie wiesz, jak pewne rzeczy zostały zrobione na różnych maszynach, nie będzie Cię kusiło, aby wykorzystywać specyfikę konkretnej implementacji.


Wyszukiwarka

Podobne podstrony:
ANSI C 0 2 TYPY, OPERATORY I WYRAŻENIA Kwalifikatory signed (ze znakiem liczby) i unsigned (bez zn
ANSI C 1 2 TYPY, OPERATORY I WYRAŻENIA Stała znakowa ’’ reprezentuje znak o wartości zero, tzw. z
ANSI C 4 2 TYPY, OPERATORY I WYRAŻENIA__.______ n = 0; for (i = 0; s[i] >= ’0’ && s[i]
ANSI C 9 TYPY, OPERATORY I WYRAŻENIA Zmienne i stałe są podstawowymi obiektami danych, jakimi posł
ANSI C 2 2 TYPY, OPERATORY I WYRAŻENIA_____— kiej zmiennej, jest poprawną wartością wyliczenia. Zm
ANSI C 3 2 TYPY, OPERATORY I WYRAŻENIA_______ W tablicy 2.1 na końcu tego rozdziału podano prioryt
ANSI C 5 2 TYPY. OPERATORY I WYRAŻENIA • Następnie, jeśli którykolwiek z argumentów ma kwalifikato
ANSI C 6 2 TYPY, OPERATORY I WYRAŻENIA unsigned long int next = 1; I* rand: daj pseudo-losowo licz
ANSI C 7 2 TYPY, OPERATORY I WYRAŻENIA możemy zapisać w bardziej zwartej postaci if (c != ’

ANSI C 8 2 TYPY, OPERATORY I WYRAŻENIA________ -077 jest wyrażeniem stałym, które może być obliczo
ANSI C 9 2 TYPY, OPERATORY I WYRAŻENIA______________ „weź i, dodaj 2, a następnie umieść wynik z p
ANSI C 0 4 FUNKCJE I STRUKTURA PROGRAMU /* getline: wczytaj wiersz do tablicy s; podaj jego długoś
ANSI C 0 4 FUNKCJE I STRUKTURA PROGRAMU-------------- zamiast int Iow, high, mid; Iow = 0; high =
ANSI C 0 6 STRUKTURY int getword(char *t int); int binsearch(char *, struct key *, int); /* zlicz
ANSI C 0 i 6 STRUKTURY Prawie wszystko, co wiąże się z polami bitowymi, zależy od implementacji. T
ANSI C 0 DODATEK A PRZEWODNIK JĘZYKA C ___——- łujących się do samych siebie: struktura lub unia mo
strukturalnych będą wsparte finansowaniem prywatnym. W praktyce oznacza to promocję finansowych
IMG0 181 (2) 180 8. Defekty struktury krystalicznej międzyatomowych. W sieci idealnej węzeł końcowy

więcej podobnych podstron