Other operators
Eine Sammlung von Operatoren, die nicht in eine der anderen Hauptkategorien passen.
|
Dieser Abschnitt ist unvollständig
Grund: Erwägen Sie einen vielseitigeren ToC für diese und andere Tabellen, die mehrere Themen abdecken |
| Operator | Operatorname | Beispiel | Beschreibung |
|---|---|---|---|
| ( ... ) | Funktionsaufruf | f ( ... ) | ruft die Funktion f () auf, mit null oder mehr Argumenten |
| , | Komma-Operator | a, b | wertet Ausdruck a aus, ignoriert dessen Rückgabewert und schließt alle Nebeneffekte ab, dann wertet Ausdruck b aus und gibt den Typ und das Ergebnis dieser Auswertung zurück |
| ( type ) | Typumwandlung | ( type ) a | wandelt den Typ von a zu type um |
| ? : | Bedingungsoperator | a ? b : c | wenn a logisch wahr ist (nicht zu Null auswertet), dann wertet Ausdruck b aus, andernfalls wertet Ausdruck c aus |
| sizeof | sizeof-Operator | sizeof a | die Größe von a in Bytes |
|
_Alignof
(seit C11) |
_Alignof-Operator | _Alignof ( type ) | die erforderliche Ausrichtung von type |
| typeof | typeof-Operatoren | typeof ( a ) | der Typ von a |
Inhaltsverzeichnis |
Funktionsaufruf
Der Funktionsaufrufausdruck hat die Form
Ausdruck
(
Argumentenliste
(optional)
)
|
|||||||||
wo
| expression | - | beliebiger Ausdruck vom Typ Zeiger-auf-Funktion (nach Lvalue-Konvertierungen ) |
| argument-list | - | kommagetrennte Liste von Ausdrücken (die keine Komma-Operatoren sein können) beliebiger vollständiger Objekttypen. Kann weggelassen werden beim Aufruf von Funktionen ohne Parameter. |
Das Verhalten des Funktionsaufrufausdrucks hängt davon ab, ob der Prototyp der aufgerufenen Funktion im Gültigkeitsbereich am Aufrufort vorhanden ist.
Aufruf einer Funktion mit einem Prototyp
|
Zusätzlich muss für jeden Parameter vom
Array-Typ
, der das Schlüsselwort
static
zwischen
[
und
]
verwendet, der Argumentausdruck einen Zeiger auf ein Element eines Arrays bezeichnen, das mindestens so viele Elemente aufweist wie in der Größenangabe des Parameters spezifiziert.
|
(seit C99) |
-
- falls ein nachgestelltes Ellipsis-Parameter vorhanden ist, werden Standardargument-Promotions für die verbleibenden Argumente durchgeführt, die für va_list verfügbar gemacht werden.
void f(char* p, int x) {} int main(void) { f("abc", 3.14); // array to pointer and float to int conversions }
Aufruf einer Funktion ohne Prototyp
1)
Die Argumente werden
in nicht spezifizierter Reihenfolge und ohne Sequenzierung ausgewertet
.
2)
Standardargument-Höherwertungen
werden für jeden Argumentausdruck durchgeführt.
3)
Zuweisung
wird durchgeführt, um den Wert jedes Arguments an den entsprechenden Funktionsparameter zu kopieren, wobei etwaige Typqualifizierer auf dem Parametertyp und dessen möglichen rekursiven Elementen oder Mitgliedern ignoriert werden.
4)
Die Funktion wird ausgeführt, und der von ihr zurückgegebene Wert wird zum Wert des Funktionsaufrufausdrucks (wenn die Funktion void zurückgibt, ist der Funktionsaufrufausdruck ein void-Ausdruck)
void f(); // no prototype int main(void) { f(1, 1.0f); // UB unless f is defined to take an int and a double } void f(int a, double c) {} Das Verhalten eines Funktionsaufrufs ohne Prototyp ist undefiniert, wenn
|
(bis C23) |
Hinweise
Die Auswertungen von expression , die die aufzurufende Funktion bezeichnen, und aller Argumente sind unsequenced zueinander (jedoch gibt es einen Sequence Point bevor der Rumpf der Funktion mit der Ausführung beginnt)
(*pf[f1()]) (f2(), f3() + f4()); // f1, f2, f3, f4 können in beliebiger Reihenfolge aufgerufen werden
Obwohl der Funktionsaufruf nur für Zeiger auf Funktionen definiert ist, funktioniert er mit Funktionsbezeichnern aufgrund der impliziten Funktion-zu-Zeiger-Konvertierung .
int f(void) { return 1; } int (*pf)(void) = f; int main(void) { f(); // f in Zeiger konvertieren, dann aufrufen (&f)(); // Zeiger auf Funktion erstellen, dann aufrufen pf(); // Funktion aufrufen (*pf)(); // Funktionsbezeichner erhalten, in Zeiger konvertieren, dann aufrufen (****f)(); // In Zeiger konvertieren, Funktion erhalten, 4x wiederholen, dann aufrufen (****pf)(); // ebenfalls OK }
Funktionen, die ungenutzte Argumente ignorieren, wie zum Beispiel printf , müssen mit einem Prototyp im Gültigkeitsbereich aufgerufen werden (der Prototyp solcher Funktionen verwendet notwendigerweise den nachgestellten Ellipsen -Parameter), um undefiniertes Verhalten zu vermeiden.
Die aktuelle Standardformulierung der Semantik zur Vorbereitung von Funktionsparametern ist fehlerhaft, da sie festlegt, dass Parameter beim Aufruf von Argumenten zugewiesen werden, was fälschlicherweise const-qualifizierte Parameter- oder Membertypen ablehnt und unangemessen die Semantik von volatile anwendet, die für Funktionsparameter auf vielen Plattformen nicht implementierbar ist. Ein Post-C11-Fehlerbericht DR427 schlug eine Änderung dieser Semantik von Zuweisung zu Initialisierung vor, wurde jedoch als kein Fehler geschlossen.
|
Ein Funktionsaufrufausdruck, bei dem expression vollständig aus einem Bezeichner besteht und dieser Bezeichner nicht deklariert ist, verhält sich so, als ob der Bezeichner deklariert wäre als extern int identifier(); // returns int and has no prototype Daher ist das folgende vollständige Programm gültiges C89: main() { int n = atoi("123"); // implicitly declares atoi as int atoi() } |
(bis C99) |
Komma-Operator
Der Komma-Operator-Ausdruck hat die Form
lhs
,
rhs
|
|||||||||
wo
| lhs | - | beliebiger Ausdruck |
| rhs | - | beliebiger Ausdruck außer einem weiteren Komma-Operator (mit anderen Worten, die Assoziativität des Komma-Operators ist links-nach-rechts) |
Zuerst wird der linke Operand, lhs , ausgewertet und sein Ergebniswert verworfen.
Dann findet ein Sequenzpunkt statt, sodass alle Nebeneffekte von lhs abgeschlossen sind.
Dann wird der rechte Operand, rhs , ausgewertet und sein Ergebnis wird durch den Komma-Operator als ein Non-Lvalue zurückgegeben.
Hinweise
Der Typ des lhs kann void sein (das heißt, es kann sich um einen Aufruf einer Funktion handeln, die void zurückgibt, oder es kann ein Ausdruck sein, der durch eine Cast -Operation zu void umgewandelt wird)
Der Komma-Operator kann in C++ ein Lvalue sein, aber niemals in C
Der Komma-Operator kann eine Struktur zurückgeben (die einzigen anderen Ausdrücke, die Strukturen zurückgeben, sind zusammengesetzte Literale, Funktionsaufrufe, Zuweisungen und der bedingte Operator)
In den folgenden Kontexten kann der Komma-Operator nicht auf der obersten Ebene eines Ausdrucks erscheinen, da das Komma eine andere Bedeutung hat:
- Argumentenliste in einem Funktionsaufruf
- Initialisierungsausdruck oder Initialisierungsliste
- Generic Selection
Wenn der Komma-Operator in einem solchen Kontext verwendet werden muss, muss er in Klammern gesetzt werden:
// int n = 2,3; // Fehler: Komma wird als Beginn des nächsten Deklarators angenommen // int a[2] = {1,2,3}; // Fehler: Mehr Initialisierer als Elemente int n = (2,3), a[2] = {(1,2),3}; // OK f(a, (t=3, t+2), c); // OK, speichert zuerst 3 in t, ruft dann f mit drei Argumenten auf
Der Top-Level-Komma-Operator ist in Array-Grenzen ebenfalls nicht erlaubt
// int a[2,3]; // Fehler int a[(2,3)]; // OK, VLA-Array der Größe 3 (VLA, da (2,3) kein konstanter Ausdruck ist)
Der Komma-Operator ist nicht erlaubt in konstanten Ausdrücken , unabhängig davon, ob er auf oberster Ebene steht oder nicht
// static int n = (1,2); // Fehler: Konstante Ausdrücke können den Komma-Operator nicht aufrufen
Cast-Operator
Siehe cast operator
Bedingter Operator
Der bedingte Operatorausdruck hat die Form
Bedingung
?
Wahr-Ausdruck
:
Falsch-Ausdruck
|
|||||||||
wo
| condition | - | ein Ausdruck skalaren Typs |
| expression-true | - | der Ausdruck, der ausgewertet wird, wenn condition ungleich Null verglichen wird |
| expression-false | - | der Ausdruck, der ausgewertet wird, wenn condition gleich Null verglichen wird |
Nur die folgenden Ausdrücke sind als expression-true und expression-false erlaubt
- zwei Ausdrücke beliebigen arithmetischen Typs
- zwei Ausdrücke desselben struct - oder union -Typs
- zwei Ausdrücke vom void-Typ
- zwei Ausdrücke vom Zeigertyp, die auf Typen zeigen, die kompatibel sind, unter Ignorierung von CVR-Qualifizierern
|
(seit C23) |
- ein Ausdruck ist ein Zeiger und der andere ist die Nullzeiger-Konstante (wie NULL ) oder ein nullptr_t -Wert (seit C23)
- ein Ausdruck ist ein Zeiger auf Objekt und der andere ist ein Zeiger auf void (möglicherweise qualifiziert)
| (seit C23) |
#define ICE(x) (sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1))) // falls x ein Integer-Konstantenausdruck ist, dann expandiert das Makro zu sizeof(*(1 ? NULL : (int *) 1)) // (void *)((x)*0l)) -> NULL // gemäß Punkt (4) konvertiert dies weiter in sizeof(int) // falls x kein Integer-Konstantenausdruck ist, dann expandiert das Makro zu // gemäß Punkt (6) (sizeof(*(void *)(x)) // Fehler aufgrund unvollständigen Typs
Hinweise
Der bedingte Operator ist niemals ein Lvalue-Ausdruck , obwohl er Objekte vom Typ Struct/Union zurückgeben kann. Die einzigen anderen Ausdrücke, die Structs zurückgeben können, sind Zuweisung , Komma , Funktionsaufruf und zusammengesetztes Literal .
Beachten Sie, dass es sich in C++ um einen Lvalue-Ausdruck handeln kann.
Siehe Operator-Präzedenz für Details zur relativen Priorität dieses Operators und Zuweisung.
Der bedingte Operator hat Rechts-nach-links-Assoziativität, was Verkettung ermöglicht
#include <assert.h> enum vehicle { bus, airplane, train, car, horse, feet }; enum vehicle choose(char arg) { return arg == 'B' ? bus : arg == 'A' ? airplane : arg == 'T' ? train : arg == 'C' ? car : arg == 'H' ? horse : feet ; } int main(void) { assert(choose('H') == horse && choose('F') == feet); }
sizeof
Operator
Siehe sizeof-Operator
_Alignof
Operator
Siehe _Alignof operator
typeof
Operatoren
Siehe typeof-Operatoren
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
-
- 6.5.2.2 Funktionsaufrufe (S: TBD)
-
- 6.5.3.4 Die sizeof- und _Alignof-Operatoren (S: TBD)
-
- 6.5.4 Typumwandlungsoperatoren (S: TBD)
-
- 6.5.15 Bedingungsoperator (S: TBD)
-
- 6.5.17 Kommaoperator (S: TBD)
-
- 6.7.3.5 Typeof-Spezifizierer (S: 115-118)
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.5.2.2 Funktionsaufrufe (S: 58-59)
-
- 6.5.3.4 Die sizeof- und _Alignof-Operatoren (S: 64-65)
-
- 6.5.4 Typumwandlungsoperatoren (S: 65-66)
-
- 6.5.15 Bedingungsoperator (S: 71-72)
-
- 6.5.17 Kommaoperator (S: 75)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.5.2.2 Funktionsaufrufe (S: 81-82)
-
- 6.5.3.4 Die sizeof- und _Alignof-Operatoren (S: 90-91)
-
- 6.5.4 Typumwandlungsoperatoren (S: 91)
-
- 6.5.15 Bedingungsoperator (S: 100)
-
- 6.5.17 Kommaoperator (S: 105)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.5.2.2 Funktionsaufrufe (S. 71-72)
-
- 6.5.3.4 Der sizeof-Operator (S. 80-81)
-
- 6.5.4 Typumwandlungsoperatoren (S. 81)
-
- 6.5.15 Bedingungsoperator (S. 90-91)
-
- 6.5.17 Kommaoperator (S. 94)
- C89/C90-Standard (ISO/IEC 9899:1990):
-
- 3.3.2.2 Funktionsaufrufe
-
- 3.3.3.4 Der sizeof-Operator
-
- 3.3.4 Typumwandlungsoperatoren
-
- 3.3.15 Bedingungsoperator
-
- 3.3.17 Kommaoperator
Siehe auch
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung |
Inkrement
Dekrement |
Arithmetisch | Logisch | Vergleich |
Mitgliederzugriff
Zugriff |
Sonstige |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
b
]
|
a
(
...
)
|
|
C++ Dokumentation
für
Andere Operatoren
|