Namensräume
Varianten
Aktionen

Zuweisungsoperatoren

Von cppreference.com
< c‎ | Sprache

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 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)
  • lhs hat den Typ (möglicherweise qualifiziert oder atomar(seit C11)) _Bool und rhs ist ein Zeiger oder ein nullptr_t-Wert(seit C23)
(seit C99)
  • lhs hat den Typ (möglicherweise qualifiziert oder atomar) nullptr_t und rhs hat den Typ nullptr_t
(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)
#include <stdio.h>
 
int main(void)
{
    int x = 10; 
    int hundred = 100; 
    int ten = 10; 
    int fifty = 50; 
 
    printf("%d %d %d %d\n", x, hundred, ten, fifty);
 
    hundred *= x; 
    ten     /= x; 
    fifty   %= x; 
 
    printf("%d %d %d %d\n", x, hundred, ten, fifty);
 
    return 0;
}

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

Operatorrangfolge

Häufige Operatoren
Zuweisung Inkrement
Dekrement
Arithmetik Logisch Vergleich Member
Zugriff
Sonstiges

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b

a[b]
*a
&a
a->b
a.b

a(...)
a, b
(type) a
a ? b : c
sizeof


_Alignof
(seit C11)
(bis C23)

alignof
(seit C23)

[bearbeiten] Siehe auch

C++ Dokumentation für Zuweisungsoperatoren