Member-Zugriffsoperatoren
Member-Zugriffsoperatoren ermöglichen den Zugriff auf die Member ihrer Operanden.
| Operator | Operatorname | Beispiel | Beschreibung |
|---|---|---|---|
| [] | Array-Subskript | a[b] | greift auf das b-te Element des Arrays a zu |
| * | Zeigerdereferenzierung | *a | dereferenziert den Zeiger a, um das Objekt oder die Funktion darauf zuzugreifen |
| & | Adresse von | &a | erstellt einen Zeiger, der auf das Objekt oder die Funktion a verweist |
| . | Member-Zugriff | a.b | greift auf Member b der struct oder union a zu |
| -> | Member-Zugriff über Zeiger | a->b | greift auf Member b der struct oder union zu, auf die a zeigt |
Inhalt |
[bearbeiten] Subskript
Der Array-Subskript-Ausdruck hat die Form
pointer-expression [ integer-expression ] |
(1) | ||||||||
integer-expression [ pointer-expression ] |
(2) | ||||||||
wobei
| pointer-expression | - | ein Ausdruck vom Typ Zeiger auf ein vollständiges Objekt |
| integer-expression | - | ein Ausdruck vom ganzzahligen Typ |
Der Subskript-Operator-Ausdruck ist ein lvalue-Ausdruck, dessen Typ der Typ des Objekts ist, auf das von pointer-expression gezeigt wird.
Per Definition ist der Subskript-Operator E1[E2] exakt identisch mit *((E1)+(E2)). Wenn pointer-expression ein Array-Ausdruck ist, durchläuft er eine 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, der gleich dem Ergebnis von integer-expression ist (oder, wenn pointer-expression auf das i-te Element eines Arrays zeigte, ist der Index des Ergebnisses i plus dem Ergebnis von integer-expression).
Hinweis: Details zu mehrdimensionalen Arrays finden Sie unter Array.
#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
[bearbeiten] Dereferenzierung
Der Dereferenzierungs- oder Indirektionsausdruck hat die Form
* pointer-expression |
|||||||||
wobei
| pointer-expression | - | ein Ausdruck eines beliebigen Zeigertyps |
Wenn pointer-expression ein Zeiger auf eine Funktion ist, ist das Ergebnis des Dereferenzierungsoperators ein Funktionsdeskriptor für diese Funktion.
Wenn pointer-expression ein Zeiger auf ein Objekt ist, ist das Ergebnis ein lvalue-Ausdruck, der das dereferenzierte Objekt bezeichnet.
Das Dereferenzieren eines Nullzeigers, eines Zeigers auf ein Objekt außerhalb seiner Lebensdauer (ein hängender Zeiger), eines falsch ausgerichteten Zeigers oder eines Zeigers mit unbestimmtem Wert ist undefiniertes Verhalten, es sei denn, der Dereferenzierungsoperator wird durch Anwendung des Adressoperator auf sein Ergebnis aufgehoben, wie in &*E.
Ausgabe
*p = 1 *p = 7
[bearbeiten] Adresse von
Der Adressoperator-Ausdruck hat die Form
& function |
(1) | ||||||||
& lvalue-expression |
(2) | ||||||||
& * expression |
(3) | ||||||||
& expression [ expression ] |
(4) | ||||||||
& und * heben sich auf, keiner von beiden wird ausgewertet& und das *, das in [] impliziert ist, heben sich auf, nur die durch [] implizierte Addition wird ausgewertet.wobei
| lvalue-expression | - | ein lvalue-Ausdruck eines beliebigen Typs, der kein Bitfeld ist und keine Register-Speicherklasse hat |
Der Adressoperator erzeugt die Nicht-lvalue-Adresse seines Operanden, die zur Initialisierung eines Zeigers auf den Typ des Operanden geeignet ist. Wenn der Operand ein Funktionsdeskriptor (1) ist, ist das Ergebnis ein Zeiger auf eine Funktion. Wenn der Operand ein Objekt (2) ist, ist das Ergebnis ein Zeiger auf ein Objekt.
Wenn der Operand der Dereferenzierungsoperator ist, wird keine Aktion ausgeführt (daher ist es in Ordnung, &* auf einen Nullzeiger anzuwenden), außer dass das Ergebnis kein lvalue ist.
Wenn der Operand ein Array-Index-Ausdruck ist, wird keine Aktion außer der Array-zu-Zeiger-Konvertierung und der Addition ausgeführt, sodass &a[N] für ein Array der Größe N gültig ist (ein Zeiger auf ein Element hinter dem Ende ist in Ordnung, dessen Dereferenzierung 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; // address of object n int (*fp)(char) = &f; // address of function f int a[3] = {1,2,3}; int *beg=a, *end=&a[3]; // same as end = a+3 }
[bearbeiten] Member-Zugriff
Der Member-Zugriffs-Ausdruck hat die Form
expression . member-name |
|||||||||
wobei
| expression | - | ein Ausdruck vom Typ struct oder union |
| member-name | - | ein Bezeichner, der einen Member der struct oder union bezeichnet, die von expression bezeichnet wird |
Der Member-Zugriffs-Ausdruck bezeichnet den benannten Member der struct oder union, die von seinem linken Operanden bezeichnet wird. Er hat dieselbe Wertkategorie wie sein linker Operand.
Wenn der linke Operand mit const oder volatile qualifiziert ist, ist das Ergebnis ebenfalls qualifiziert. Wenn der linke Operand atomar ist, ist das Verhalten undefiniert.
Hinweis: Zusätzlich zu Bezeichnern, die Objekte von struct- oder union-Typen bezeichnen, können die folgenden Ausdrücke struct- oder union-Typen haben: Zuweisung, Funktionsaufruf, Kommaoperator, Bedingungsoperator und zusammengesetzte Literale.
#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, changes the member of s int n = f().x; // f() is an expression of type struct s // f().x = 1; // Error: this member access expression is not an lvalue const struct s sc; // sc.x = 3; // Error: sc.x is const, can't be assigned union { int x; double d; } u = {1}; u.d = 0.1; // changes the active member of the union }
[bearbeiten] Member-Zugriff über Zeiger
Der Member-Zugriffs-Ausdruck hat die Form
expression -> member-name |
|||||||||
wobei
| expression | - | ein Ausdruck vom Typ Zeiger auf struct oder union |
| member-name | - | ein Bezeichner, der einen Member der struct oder union bezeichnet, auf die von expression gezeigt wird |
Der Member-Zugriffs-Ausdruck über Zeiger bezeichnet den benannten Member 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, mit const oder volatile qualifiziert ist, ist das Ergebnis ebenfalls qualifiziert. Wenn der Typ, auf den der linke Operand zeigt, atomar ist, ist das Verhalten undefiniert.
#include <stdio.h> struct s {int x;}; int main(void) { struct s s={1}, *p = &s; p->x = 7; // changes the value of s.x through the pointer printf("%d\n", p->x); // prints 7 }
[bearbeiten] Fehlerberichte
Die folgenden verhaltensändernden Defect Reports 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 |
wurde aufhebbar gemacht |
[bearbeiten] Referenzen
- C17-Standard (ISO/IEC 9899:2018)
- 6.5.2.1 Array subscripting (S. 57-58)
- 6.5.2.3 Structure and union members (S. 58-59)
- 6.5.3.2 Address and indirection operators (S. 59-61)
- C11-Standard (ISO/IEC 9899:2011)
- 6.5.2.1 Array subscripting (S. 80)
- 6.5.2.3 Structure and union members (S. 82-84)
- 6.5.3.2 Address and indirection operators (S. 88-89)
- C99-Standard (ISO/IEC 9899:1999)
- 6.5.2.1 Array subscripting (S. 70)
- 6.5.2.3 Structure and union members (S. 72-74)
- 6.5.3.2 Address and indirection operators (S. 78-79)
- C89/C90-Standard (ISO/IEC 9899:1990)
- 3.3.2.1 Array subscripting
- 3.3.2.3 Structure and union members
- 3.3.3.2 Address and indirection operators
[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(...) |
| C++ Dokumentation für Member-Zugriffsoperatoren
|