Zuweisungsoperatoren
Zuweisungs- und zusammengesetzte Zuweisungsoperatoren sind binäre Operatoren, die die Variable links von ihnen mit dem Wert rechts von ihnen modifizieren.
| Operator | Operatorname | Beispiel | Beschreibung | Äquivalent zu |
|---|---|---|---|---|
| = | einfache Zuweisung | a = b | a wird gleich b | N/A |
| += | Addition Zuweisung | a += b | a wird gleich der Summe von a und b | a = a + b |
| -= | Subtraktionszuweisung | a -= b | a wird gleich der Differenz von a und b | a = a - b |
| *= | Multiplikationszuweisung | a *= b | a wird gleich dem Produkt von a und b | a = a * b |
| /= | Divisionszuweisung | a /= b | a wird gleich dem Quotienten von a geteilt durch b | a = a / b |
| %= | Modulo-Zuweisung | a %= b | a wird gleich dem Rest von a geteilt durch b | a = a % b |
| &= | Bitweises AND-Zuweisung | a &= b | a wird gleich dem bitweisen AND von a und b | a = a & b |
| |= | Bitweises OR-Zuweisung | a |= b | a wird gleich dem bitweisen OR von a und b | a = a | b |
| ^= | Bitweises XOR-Zuweisung | a ^= b | a wird gleich dem bitweisen XOR von a und b | a = a ^ b |
| <<= | Bitweises Links-Shift-Zuweisung | a <<= b | a wird gleich a links-verschoben um b | a = a << b |
| >>= | Bitweises Rechts-Shift-Zuweisung | a >>= b | a wird gleich a rechts-verschoben um b | a = a >> b |
Inhalt |
[bearbeiten] Einfache Zuweisung
Die Ausdrücke für einfache Zuweisungsoperatoren haben die Form
lhs = rhs |
|||||||||
wobei
| lhs | - | ausdruck eines modifizierbaren lvalues jeden vollständigen Objekttyps |
| rhs | - | ausdruck beliebigen Typs, der implizit in lhs konvertierbar ist oder mit lhs kompatibel ist |
Die Zuweisung führt eine implizite Konvertierung vom Wert von rhs in den Typ von lhs durch und ersetzt dann den Wert im von lhs bezeichneten Objekt mit dem konvertierten Wert von rhs.
Die Zuweisung gibt auch den gleichen Wert zurück wie derjenige, der in lhs gespeichert wurde (sodass Ausdrücke wie a = b = c möglich sind). Die Wertkategorie des Zuweisungsoperators ist non-lvalue (sodass Ausdrücke wie (a=b)=c ungültig sind).
rhs und lhs müssen eine der folgenden Bedingungen erfüllen:
- beide lhs und rhs haben einen kompatiblen struct- oder union-Typ, oder..
- rhs muss implizit in lhs konvertierbar sein, was bedeutet:
- beide lhs und rhs haben arithmetische Typen, in diesem Fall kann lhs volatile-qualifiziert sein oder atomar(seit C11)
- beide lhs und rhs haben Zeiger auf kompatible (Qualifizierer ignoriert) Typen, oder einer der Zeiger ist ein Zeiger auf void, und die Konvertierung würde keine Qualifizierer zum Zeigertyp hinzufügen. lhs kann volatile oder restrict(seit C99)-qualifiziert sein oder atomar(seit C11).
- lhs ist ein (möglicherweise qualifizierter oder atomarer(seit C11)) Zeiger und rhs ist eine Nullzeigerkonstante wie NULL oder ein nullptr_t-Wert(seit C23)
|
(seit C99) |
| (seit C23) |
[bearbeiten] Hinweise
Wenn rhs und lhs sich im Speicher überlappen (z. B. sie sind Mitglieder derselben Union), ist das Verhalten undefiniert, es sei denn, die Überlappung ist exakt und die Typen sind kompatibel.
Obwohl Arrays nicht zuweisbar sind, ist ein in eine Struktur verpacktes Array einem anderen Objekt desselben (oder eines kompatiblen) Strukturtyps zuweisbar.
Der Nebeneffekt der Aktualisierung von lhs ist sequenziert nach der Auswertung der Werte, aber nicht die Nebeneffekte von lhs und rhs selbst und die Auswertungen der Operanden sind, wie üblich, unsequenziert zueinander (sodass Ausdrücke wie i=++i; undefiniert sind)
Die Zuweisung entfernt zusätzliche Bereiche und Präzision von Gleitkommaausdrücken (siehe FLT_EVAL_METHOD).
In C++ sind Zuweisungsoperatoren lvalue-Ausdrücke, in C nicht.
#include <stdio.h> int main(void) { // integers int i = 1, j = 2, k = 3; // initialization, not assignment i = j = k; // values of i and j are now 3 // (i = j) = k; // Error: lvalue required printf("%d %d %d\n", i, j, k); // pointers const char c = 'A'; // initialization; not assignment const char *p = &c; // initialization; not assignment const char **cpp = &p; // initialization; not assignment // cpp = &p; // Error: char** is not convertible to const char** *cpp = &c; // OK, char* is convertible to const char* printf("%c \n", **cpp); cpp = 0; // OK, null pointer constant is convertible to any pointer // arrays int arr1[2] = {1,2}, arr2[2] = {3, 4}; // arr1 = arr2; // Error: cannot assign to an array printf("arr1[0]=%d arr1[1]=%d arr2[0]=%d arr2[1]=%d\n", arr1[0], arr1[1], arr2[0], arr2[1]); struct { int arr[2]; } sam1 = { {5, 6} }, sam2 = { {7, 8} }; sam1 = sam2; // OK: can assign arrays wrapped in structs printf("%d %d \n", sam1.arr[0], sam1.arr[1]); }
Ausgabe
3 3 3 A arr1[0]=1 arr1[1]=2 arr2[0]=3 arr2[1]=4 7 8
[bearbeiten] Zusammengesetzte Zuweisung
Die Ausdrücke für zusammengesetzte Zuweisungsoperatoren haben die Form
| lhs op rhs | |||||||||
wobei
| op | - | einer von *=, /= %=, += -=, <<=, >>=, &=, ^=, |= |
| lhs, rhs | - | Ausdrücke mit arithmetischen Typen (wobei lhs qualifiziert oder atomar sein kann), außer wenn op += oder -= ist, was auch Zeigertypen mit denselben Einschränkungen wie + und - akzeptiert |
Der Ausdruck lhs @= rhs ist exakt gleich lhs = lhs @ ( rhs ), außer dass lhs nur einmal ausgewertet wird.
|
Wenn lhs einen atomaren Typ hat, verhält sich die Operation als einzelne atomare Lese-Modifikations-Schreib-Operation mit der Speicherreihenfolge memory_order_seq_cst. Für ganzzahlige atomare Typen ist die zusammengesetzte Zuweisung @= äquivalent zu T1* addr = &lhs; T2 val = rhs; T1 old = *addr; T1 new; do { new = old @ val } while (!atomic_compare_exchange_strong(addr, &old, new); |
(seit C11) |
Ausgabe
10 100 10 50 10 1000 1 0
[bearbeiten] Referenzen
- C17-Standard (ISO/IEC 9899:2018)
- 6.5.16 Zuweisungsoperatoren (S. 72-73)
- C11-Standard (ISO/IEC 9899:2011)
- 6.5.16 Zuweisungsoperatoren (S. 101-104)
- C99-Standard (ISO/IEC 9899:1999)
- 6.5.16 Zuweisungsoperatoren (S. 91-93)
- C89/C90-Standard (ISO/IEC 9899:1990)
- 3.3.16 Zuweisungsoperatoren
[bearbeiten] Siehe auch
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung | Inkrement Dekrement |
Arithmetik | Logisch | Vergleich | Member Zugriff |
Sonstiges |
|
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
[bearbeiten] Siehe auch
| C++ Dokumentation für Zuweisungsoperatoren
|