Piszesz co masz na myśli. Kompilator czyta, co chce.
Jeśli kiedykolwiek patrzyłeś na linię kodu C i byłeś przekonany, że robi jedną rzecz, a potem obserwowałeś, jak robi coś zupełnie innego, zetknąłeś się z pierwszeństwem operatora. To nie jest błąd. Jest to cecha języka, która gryzie nawet doświadczonych programistów.
Weźmy tę prostą arytmetykę:
x=5+3*6;
W szkole matematycy mówią: najpierw dodawanie. W C mówią: nie. Mnożenie i dzielenie są na wyższym poziomie niż dodawanie i odejmowanie. Kompilator najpierw mnoży 3 przez 6, następnie dodaje 5. X otrzymuje 23. Nie 48. Właśnie straciłeś punkty na teście. Lub, co gorsza, we wdrożeniu produkcyjnym.
Zamieszanie pogłębia się, gdy mieszasz operatory ze składnią.
Spójrz na tę reklamę:
znak *a[10];
Czy a jest wskaźnikiem do tablicy składającej się z 10 znaków? A może jest to tablica 10 wskaźników znakowych?
Nie znając konkretnych zasad pierwszeństwa, zgadujesz. W C nawiasy kwadratowe [] są ograniczone bardziej rygorystycznie niż wskaźniki *. Jest to więc tablica zawierająca 10 wskaźników znakowych.
Ma to znaczenie, ponieważ C nie jest analizowany jak angielski. Rozumie się to jako sztywną hierarchię.
Możesz napisać kod, który wygląda poprawnie, ale po cichu kończy się niepowodzeniem ze względu na pierwszeństwo.
Przyjrzyjmy się arytmetyce wskaźników w połączeniu z dostępem do struktur.
*pi = 10;
To nie działa zgodnie z oczekiwaniami. Operator kropki . ma wyższy priorytet niż operator dereferencji *. Kompilator próbuje uzyskać dostęp do elementu „i” obiektu wskazywanego przez „p” przed wyłuskaniem „p”. Ale „p” jest wskaźnikiem, a nie strukturą. Kompilator się potyka. Albo, co gorsza, interpretuje pamięć w sposób powodujący uszkodzenie danych.
Musisz postawić na swoim.
(*p).i = 10;
Nawiasy wygrywają. Zawsze.
Hierarchia operatorów
Kernighan i Ritchie, architekci C, w swoim klasycznym tekście określili priorytet. Poniższa tabela przedstawia kolejność. Górna linia ma najwyższy priorytet. Dół jest najmniejszy.
- Nawiasy
()i Indeksacja[] - Od lewej do prawej.
- Operatory jednoargumentowe
++,--,+,-,!,~,(typ),*(dereferencja),&(adres),sizeof - Od prawej do lewej.
- Multiplikatywność
*,/,% - Od lewej do prawej.
- Dodatek
+,- - Od lewej do prawej.
- Shift
<<,>> - Od lewej do prawej.
- Relacje
<,<=,>,>= - Od lewej do prawej.
- Równość
==,!= - Od lewej do prawej.
- Bitowe ORAZ
& - Od lewej do prawej.
- Bitowy XOR
^



























