C Operator-Rangfolge
Die folgende Tabelle listet die Rangfolge und Assoziativität von C-Operatoren auf. Operatoren sind von oben nach unten in absteigender Rangfolge aufgeführt.
| Rangfolge | Operator | Beschreibung | Assoziativität |
|---|---|---|---|
| 1 | ++ --
|
Suffix-/Post-Inkrement und -Dekrement | Links nach rechts |
()
|
Funktionsaufruf | ||
[]
|
Array-Indizierung | ||
.
|
Zugriff auf Struktur- und Union-Member | ||
->
|
Zugriff auf Struktur- und Union-Member über Zeiger | ||
(Typ){Liste}
|
Compound Literal(C99) | ||
| 2 | ++ --
|
Präfix-Inkrement und -Dekrement[Anm. 1] | Rechts nach links |
+ -
|
Unäres Plus und Minus | ||
! ~
|
Logisches NICHT und bitweises NICHT | ||
(Typ)
|
Typumwandlung (Cast) | ||
*
|
Indirektion (Dereferenzierung) | ||
&
|
Adress-Operator | ||
sizeof
|
Größe von[Anm. 2] | ||
_Alignof
|
Ausrichtungsanforderung(C11) | ||
| 3 | * / %
|
Multiplikation, Division und Rest | Links nach rechts |
| 4 | + -
|
Addition und Subtraktion | |
| 5 | << >>
|
Bitweises Links- und Rechts-Shift | |
| 6 | < <=
|
Für relationale Operatoren < bzw. ≤ | |
> >=
|
Für relationale Operatoren > bzw. ≥ | ||
| 7 | == !=
|
Für relationale Operatoren = bzw. ≠ | |
| 8 | &
|
Bitweises UND | |
| 9 | ^
|
Bitweises XOR (exklusives ODER) | |
| 10 | |
|
Bitweises ODER (inklusives ODER) | |
| 11 | &&
|
Logisches UND | |
| 12 | ||
|
Logisches ODER | |
| 13 | ?:
|
Ternärer bedingter Operator[Anm. 3] | Rechts nach links |
| 14[Anm. 4] | =
|
Einfache Zuweisung | |
+= -=
|
Zuweisung durch Summe und Differenz | ||
*= /= %=
|
Zuweisung durch Produkt, Quotient und Rest | ||
<<= >>=
|
Zuweisung durch bitweises Links- und Rechts-Shift | ||
&= ^= |=
|
Zuweisung durch bitweises AND, XOR und OR | ||
| 15 | ,
|
Komma | Links nach rechts |
- ↑ Der Operand von Präfix
++und--darf kein Typ-Cast sein. Diese Regel verbietet grammatikalisch einige Ausdrücke, die ohnehin semantisch ungültig wären. Einige Compiler ignorieren diese Regel und erkennen die Ungültigkeit semantisch. - ↑ Der Operand von
sizeofdarf kein Typ-Cast sein: Der Ausdruck sizeof (int) * p wird eindeutig als (sizeof(int)) * p interpretiert und nicht als sizeof((int)*p). - ↑ Der Ausdruck in der Mitte des bedingten Operators (zwischen
?und:) wird so geparst, als ob er in Klammern stünde: seine Rangfolge relativ zu?:wird ignoriert. - ↑ Linke Operanden von Zuweisungsoperatoren müssen unäre (Rangfolge 2, nicht-Cast) Ausdrücke sein. Diese Regel verbietet grammatikalisch einige Ausdrücke, die ohnehin semantisch ungültig wären. Viele Compiler ignorieren diese Regel und parsen sie semantisch. Zum Beispiel ist e = a < d ? a++ : a = d ein Ausdruck, der aufgrund dieser Regel nicht geparst werden kann. Viele Compiler ignorieren diese Regel jedoch und parsen ihn als e = ( ((a < d) ? (a++) : a) = d ) und geben dann einen Fehler aus, da er semantisch ungültig ist.
Beim Parsen eines Ausdrucks wird ein Operator, der in einer Zeile aufgeführt ist, fester (als ob durch Klammern) an seine Argumente gebunden als jeder Operator, der in einer darunter liegenden Zeile aufgeführt ist. Zum Beispiel wird der Ausdruck *p++ als *(p++) geparst und nicht als (*p)++.
Operatoren, die sich in derselben Zelle befinden (es können mehrere Zeilen von Operatoren in einer Zelle aufgeführt sein), werden mit derselben Rangfolge in der angegebenen Richtung ausgewertet. Zum Beispiel wird der Ausdruck a=b=c als a=(b=c) geparst und nicht als (a=b)=c, aufgrund der Rechts-nach-links-Assoziativität.
[bearbeiten] Anmerkungen
Rangfolge und Assoziativität sind unabhängig von der Auswertungsreihenfolge.
Der Standard selbst gibt keine Rangfolgen an. Sie leiten sich aus der Grammatik ab.
In C++ hat der bedingte Operator die gleiche Rangfolge wie Zuweisungsoperatoren, und Präfix-++ und -- sowie Zuweisungsoperatoren haben nicht die Einschränkungen bezüglich ihrer Operanden.
Die Angabe der Assoziativität ist für unäre Operatoren redundant und dient nur der Vollständigkeit: unäre Präfix-Operatoren assoziieren immer von rechts nach links (sizeof ++*p ist sizeof(++(*p))) und unäre Postfix-Operatoren assoziieren immer von links nach rechts (a[1][2]++ ist ((a[1])[2])++). Beachten Sie, dass die Assoziativität für Member-Zugriffsoperatoren bedeutsam ist, obwohl sie mit unären Postfix-Operatoren gruppiert sind: a.b++ wird als (a.b)++ geparst und nicht als a.(b++).
[bearbeiten] Referenzen
- C17-Standard (ISO/IEC 9899:2018)
- A.2.1 Ausdrücke
- C11-Standard (ISO/IEC 9899:2011)
- A.2.1 Ausdrücke
- C99-Standard (ISO/IEC 9899:1999)
- A.2.1 Ausdrücke
- C89/C90-Standard (ISO/IEC 9899:1990)
- A.1.2.1 Ausdrücke
[bearbeiten] Siehe auch
Auswertungsreihenfolge von Operatorargumenten zur Laufzeit.
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung | Inkrement Dekrement |
Arithmetik | Logisch | Vergleich | Member Zugriff |
Sonstiges |
|
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
| C++-Dokumentation für C++ Operator-Rangfolge
|