Member access operators
Member-Zugriffsoperatoren ermöglichen den Zugriff auf die Member ihrer Operanden.
| Operator | Operatorname | Beispiel | Beschreibung |
|---|---|---|---|
| [ ] | Array-Subscript | a [ b ] | Zugriff auf das b -te Element des Arrays a |
| * | Pointer-Dereferenzierung | * a | Dereferenzierung des Pointers a , um auf das Objekt oder die Funktion zuzugreifen, auf die er verweist |
| & | Adresse von | & a | Erzeugt einen Pointer, der auf das Objekt oder die Funktion a verweist |
| . | Member-Zugriff | a. b | Zugriff auf Member b der struct oder union a |
| - > | Member-Zugriff durch Pointer | a - > b | Zugriff auf Member b der struct oder union , auf die durch a gezeigt wird |
Inhaltsverzeichnis |
Indexoperator
Der Array-Subscript-Ausdruck hat die Form
Zeigerausdruck
[
Ganzzahlausdruck
]
|
(1) | ||||||||
Ganzzahlausdruck
[
Zeigerausdruck
]
|
(2) | ||||||||
wo
| pointer-expression | - | ein Ausdruck vom Typ Zeiger auf vollständiges Objekt |
| integer-expression | - | ein Ausdruck vom Ganzzahltyp |
Der Subskript-Operator-Ausdruck ist ein Lvalue-Ausdruck , dessen Typ der Typ des Objekts ist, auf das durch pointer-expression gezeigt wird.
Per Definition ist der Indexoperator E1 [ E2 ] exakt identisch zu * ( ( E1 ) + ( E2 ) ) . Wenn pointer-expression ein Array-Ausdruck ist, unterliegt es der Lvalue-zu-Rvalue-Konvertierung und wird zu einem Zeiger auf das erste Element des Arrays.
Aufgrund der Definition der Addition zwischen einem Zeiger und einer Ganzzahl ist das Ergebnis das Element des Arrays mit dem Index gleich dem Ergebnis des integer-expression (oder, falls pointer-expression auf das i-te Element eines Arrays zeigte, ist der Index des Ergebnisses i plus das Ergebnis der integer-expression )
Hinweis: siehe array für Details zu mehrdimensionalen Arrays.
#include <stdio.h> int main(void) { int a[3] = {1,2,3}; printf("%d %d\n", a[2], // n == 3 2[a]); // same, n == 3 a[2] = 7; // subscripts are lvalues int n[2][3] = {{1,2,3},{4,5,6}}; int (*p)[3] = &n[1]; // elements of n are arrays printf("%d %d %d\n", (*p)[0], p[0][1], p[0][2]); // access n[1][] via p int x = n[1][2]; // applying [] again to the array n[1] printf("%d\n", x); printf("%c %c\n", "abc"[2], 2["abc"]); // string literals are arrays too }
Ausgabe:
3 3 4 5 6 6 c c
Dereferenzierung
Der Dereferenzierungs- oder Indirektions- Ausdruck hat die Form
*
Zeigerausdruck
|
|||||||||
wo
| pointer-expression | - | ein Ausdruck eines beliebigen Zeigertyps |
Wenn pointer-expression ein Zeiger auf eine Funktion ist, dann ist das Ergebnis des Dereferenzierungsoperators ein Funktionsbezeichner für diese Funktion.
Wenn pointer-expression ein Zeiger auf ein Objekt ist, ist das Ergebnis ein Lvalue-Ausdruck , der das referenzierte Objekt bezeichnet.
Das Dereferenzieren eines Nullzeigers, eines Zeigers auf ein Objekt außerhalb seiner Lebensdauer (eines hängenden Zeigers), eines falsch ausgerichteten Zeigers oder eines Zeigers mit undefiniertem Wert ist undefiniertes Verhalten, außer wenn der Dereferenzierungsoperator durch Anwendung des Adressoperators auf sein Ergebnis aufgehoben wird, wie in & * E .
Ausgabe:
*p = 1 *p = 7
Adresse von
Der Adressoperator-Ausdruck hat die Form
&
Funktion
|
(1) | ||||||||
&
Lvalue-Ausdruck
|
(2) | ||||||||
&
*
Ausdruck
|
(3) | ||||||||
&
Ausdruck
[
Ausdruck
]
|
(4) | ||||||||
&
und
*
heben sich gegenseitig auf, keiner wird ausgewertet
&
und das
*
, das in
[]
impliziert ist, heben sich gegenseitig auf, nur die in
[]
implizierte Addition wird ausgewertet.
wo
| lvalue-expression | - | ein lvalue -Ausdruck beliebigen Typs, der kein Bitfeld ist und nicht über die register -Speicherklasse verfügt |
Der Adressoperator erzeugt die Nicht-Lvalue -Adresse seines Operanden, geeignet zur Initialisierung eines Zeigers auf den Typ des Operanden. Wenn der Operand ein Funktionsbezeichner ist (1) , ist das Ergebnis ein Zeiger auf Funktion. Wenn der Operand ein Objekt ist (2) , ist das Ergebnis ein Zeiger auf Objekt.
Wenn der Operand der Dereferenzierungsoperator ist, wird keine Aktion durchgeführt (daher ist es zulässig, &* auf einen Nullzeiger anzuwenden), außer dass das Ergebnis kein L-Wert ist.
Wenn der Operand ein Array-Index-Ausdruck ist, wird außer der Array-zu-Zeiger-Konvertierung und der Addition keine Aktion durchgeführt, daher ist &a[N] gültig für ein Array der Größe N (das Erhalten eines Zeigers eins hinter dem Ende ist erlaubt, das Dereferenzieren nicht, aber die Dereferenzierung hebt sich in diesem Ausdruck auf).
int f(char c) { return c;} int main(void) { int n = 1; int *p = &n; // Adresse des Objekts n int (*fp)(char) = &f; // Adresse der Funktion f int a[3] = {1,2,3}; int *beg=a, *end=&a[3]; // gleichbedeutend mit end = a+3 }
Memberzugriff
Der Member-Zugriffsausdruck hat die Form
Ausdruck
.
Elementname
|
|||||||||
wo
| expression | - | ein Ausdruck vom Typ struct oder union |
| member-name | - | ein identifier , der ein Mitglied der durch expression bezeichneten Struktur oder Union benennt |
Der Member-Zugriffsausdruck bezeichnet das benannte Member der struct oder union , die durch seinen linken Operanden bezeichnet wird. Er hat dieselbe value category wie sein linker Operand.
Wenn der linke Operand const - oder volatile -qualifiziert ist, ist das Ergebnis ebenfalls qualifiziert. Wenn der linke Operand atomic ist, ist das Verhalten undefiniert.
Hinweis: Neben Bezeichnern, die Objekte vom Typ struct oder union benennen, können die folgenden Ausdrücke Typen struct oder union haben: assignment , function call , comma operator , conditional operator , und compound literal .
#include <stdio.h> struct s {int x;}; struct s f(void) { return (struct s){1}; } int main(void) { struct s s; s.x = 1; // ok, ändert das Mitglied von s int n = f().x; // f() ist ein Ausdruck vom Typ struct s // f().x = 1; // Fehler: Dieser Mitgliedszugriffsausdruck ist kein Lvalue const struct s sc; // sc.x = 3; // Fehler: sc.x ist const, kann nicht zugewiesen werden union { int x; double d; } u = {1}; u.d = 0.1; // ändert das aktive Mitglied der Union }
Memberzugriff über Zeiger
Der Member-Zugriffsausdruck hat die Form
Ausdruck
->
Elementname
|
|||||||||
wo
| expression | - | ein Ausdruck vom Typ pointer zu struct oder union |
| member-name | - | ein identifier der ein Element der struct oder union benennt, auf die durch expression gezeigt wird |
Der Zugriff auf Elemente durch Zeigerausdrücke bezeichnet das benannte Element des struct - oder union -Typs, auf den sein linker Operand zeigt. Seine Wertkategorie ist immer lvalue
Wenn der Typ, auf den der linke Operand zeigt, const - oder volatile -qualifiziert ist, ist das Ergebnis ebenfalls qualifiziert. Wenn der Typ, auf den der linke Operand zeigt, atomic ist, ist das Verhalten undefiniert.
#include <stdio.h> struct s {int x;}; int main(void) { struct s s={1}, *p = &s; p->x = 7; // ändert den Wert von s.x durch den Zeiger printf("%d\n", p->x); // gibt 7 aus }
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| DR 076 | C89 |
unnötige Indirektion konnte nicht durch
&
aufgehoben werden
|
aufhebbar gemacht |
Referenzen
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.5.2.1 Array-Subscripting (S: 57-58)
-
- 6.5.2.3 Struktur- und Union-Member (S: 58-59)
-
- 6.5.3.2 Adress- und Dereferenzierungsoperatoren (S: 59-61)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.5.2.1 Array-Subscript (S. 80)
-
- 6.5.2.3 Struktur- und Union-Elemente (S. 82-84)
-
- 6.5.3.2 Adress- und Dereferenzierungsoperatoren (S. 88-89)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.5.2.1 Array-Subscripting (S. 70)
-
- 6.5.2.3 Struktur- und Union-Member (S. 72-74)
-
- 6.5.3.2 Adress- und Dereferenzierungsoperatoren (S. 78-79)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 3.3.2.1 Array-Subscript
-
- 3.3.2.3 Struktur- und Union-Member
-
- 3.3.3.2 Adress- und Dereferenzierungsoperatoren
Siehe auch
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung |
Inkrement
Dekrement |
Arithmetisch | Logisch | Vergleich |
Member-Zugriff
Zugriff |
Sonstige |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
b
]
|
a
(
...
)
|
|
C++ Dokumentation
für
Memberzugriffsoperatoren
|