C-Operator-Priorität
Die folgende Tabelle listet die Priorität und Assoziativität von C-Operatoren auf. Die Operatoren sind von oben nach unten in absteigender Priorität aufgeführt.
| Priorität | Operator | Beschreibung | Assoziativität |
|---|---|---|---|
| 1 | ++ --
|
Suffix-/Postfix-Inkrement und -Dekrement | Links-nach-rechts |
()
|
Funktionsaufruf | ||
[]
|
Array-Indizierung | ||
.
|
Struktur- und Union-Mitgliedszugriff | ||
->
|
Struktur- und Union-Mitgliedszugriff über Zeiger | ||
(type){list}
|
Verbundliteral(C99) | ||
| 2 | ++ --
|
Präfix-Inkrement und -Dekrement[1] | Rechts-nach-links |
+ -
|
Unäres Plus und Minus | ||
! ~
|
Logisches NICHT und bitweises NICHT | ||
(type)
|
Cast | ||
*
|
Dereferenzierung | ||
&
|
Adresse-von | ||
sizeof
|
Size-of[2] | ||
_Alignof
|
Ausrichtungsanforderung(C11) | ||
| 3 | * / %
|
Multiplikation, Division und Rest | Links-nach-rechts |
| 4 | + -
|
Addition und Subtraktion | |
| 5 | << >>
|
Bitweise Links- und Rechtsverschiebung | |
| 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 Bedingungsoperator[3] | Rechts-nach-links |
| 14[4] | =
|
Einfache Zuweisung | |
+= -=
|
Zuweisung durch Summe und Differenz | ||
*= /= %=
|
Zuweisung durch Produkt, Quotient und Rest | ||
<<= >>=
|
Zuweisung durch bitweise Links- und Rechtsverschiebung | ||
&= ^= |=
|
Zuweisung durch bitweises UND, XOR und ODER | ||
| 15 | ,
|
Komma | Links-nach-rechts |
- ↑ Der Operand von Präfix
++und--kann kein Typ-Cast sein. Diese Regel verbietet grammatikalisch einige Ausdrücke, die semantisch ohnehin ungültig wären. Manche Compiler ignorieren diese Regel und erkennen die Ungültigkeit semantisch. - ↑ Der Operand von
sizeofkann kein Typ-Cast sein: Der Ausdrucksizeof (int) * pwird eindeutig als(sizeof(int)) * pinterpretiert, nicht alssizeof((int)*p). - ↑ Der Ausdruck in der Mitte des Bedingungsoperators (zwischen
?und:) wird so analysiert, als ob er in Klammern stünde: seine Priorität relativ zu?:wird ignoriert. - ↑ Die linken Operanden von Zuweisungsoperatoren müssen unäre Ausdrücke (Ebene-2-nicht-Cast) sein. Diese Regel verbietet grammatikalisch einige Ausdrücke, die semantisch ohnehin ungültig wären. Viele Compiler ignorieren diese Regel und erkennen die Ungültigkeit semantisch. Beispielsweise ist
e = a < d ? a++ : a = dein Ausdruck, der aufgrund dieser Regel nicht analysiert werden kann. Viele Compiler ignorieren diese Regel jedoch und analysieren ihn alse = ( ((a < d) ? (a++) : a) = d ), um dann einen Fehler zu geben, da er semantisch ungültig ist.
Beim Analysieren eines Ausdrucks bindet ein Operator, der in einer Zeile aufgeführt ist, stärker (wie durch Klammern) an seine Argumente als jeder Operator, der in einer weiter unten stehenden Zeile aufgeführt ist. Beispielsweise wird der Ausdruck *p++ als *(p++) analysiert 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 Priorität in der angegebenen Richtung ausgewertet. Beispielsweise wird der Ausdruck a = b = c als a = (b = c) analysiert und nicht als (a = b) = c aufgrund der Rechts-nach-links-Assoziativität.
Anmerkungen
Priorität und Assoziativität sind unabhängig von der Auswertungsreihenfolge.
Der Standard selbst gibt keine Prioritätsebenen an. Sie werden aus der Grammatik abgeleitet.
In C++ hat der Bedingungsoperator dieselbe Priorität wie Zuweisungsoperatoren, und Präfix ++ und -- sowie Zuweisungsoperatoren haben keine Einschränkungen bezüglich ihrer Operanden.
Die Angabe der Assoziativität ist für unäre Operatoren redundant und wird nur der Vollständigkeit halber gezeigt: Unäre Präfixoperatoren assoziieren immer rechts-nach-links (sizeof ++*p ist sizeof(++(*p))) und unäre Postfixoperatoren assoziieren immer links-nach-rechts (a[1][2]++ ist ((a[1])[2])++). Beachten Sie, dass die Assoziativität für Mitgliedszugriffsoperatoren von Bedeutung ist, obwohl sie mit unären Postfixoperatoren gruppiert werden: a.b++ wird als (a.b)++ analysiert und nicht als a.(b++).
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
- A.3.1 Ausdrücke
- 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
Siehe auch
Auswertungsreihenfolge von Operatorargumenten zur Laufzeit.
| Gebräuchliche Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung | Inkrement Dekrement |
arithmetisch | logisch | Vergleich | Mitglieds- zugriff |
sonstige |
|
|
|
|
|
|
|
|
C++-Dokumentation für C++-Operator-Priorität
|