Dereferenzierungs- und Address-of-Operatoren
Der unäre Dereferenzierungsoperator (*
) greift indirekt über einen Zeiger auf einen Wert zu. Der Operand muss ein Zeigertyp sein. Das Ergebnis des Vorgangs ist der Wert, der vom Operanden adressiert wird, also der Wert bei der Adresse, auf die der Operand zeigt. Der Typ, den der Operand adressiert, ist der Ergebnistyp.
Das Ergebnis des Dereferenzierungsoperators ist type, wenn der Operand vom Typ pointer to type ist. Wenn der Operand auf eine Funktion verweist, ist das Ergebnis ein Funktionsbezeichner. Wenn er auf ein Objekt zeigt, ist das Ergebnis ein lvalue, der das Objekt festlegt.
Wenn der Zeigerwert unzulässig ist, ist das Ergebnis des Dereferenzierungsoperators nicht definiert. Hier sehen Sie einige der häufigsten Bedingungen, die einen Zeigerwert ungültig machen:
Der Zeiger ist ein NULL-Zeiger.
Der Zeiger gibt die Adresse eines Elements nach dem Ende der Lebensdauer zum Zeitpunkt des Verweises an. (Beispiel: Ein Objekt, das außerhalb des Bereichs liegt oder das freigegeben wurde.)
Der Zeiger gibt eine Adresse an, die nicht ordnungsgemäß auf den Objekttyp, auf den gezeigt wird, ausgerichtet ist.
Der Zeiger gibt eine Adresse an, die nicht vom ausgeführten Programm verwendet wird.
Der unäre address-of-Operator ( &
) gibt die Adresse seines Operanden aus. Der Operand muss eines der folgenden Dinge sein:
Ein lvalue, der ein Objekt bestimmt, das nicht deklariert
register
und kein Bitfeld ist.Das Ergebnis einer unärer Ableitung (
*
) oder eines Array-Ableitungsoperators ([]
).Ein Funktionsdesignator.
Das Ergebnis ist für einen Operanden des Typs operand_type vom Typ pointer to operand_type.
Wenn der Operand das Ergebnis eines unären *
-Operators ist, wird keiner der Operatoren ausgewertet, und das Ergebnis ist so, als seien beide übersprungen worden. Das Ergebnis ist kein lvalue, und die Einschränkungen der Operatoren gelten weiterhin. Wenn der Operand das Ergebnis eines []
-Operators ist, werden der &
-Operator und der unäre *
-Operator, die vom []
-Operator impliziert werden, nicht ausgewertet. Das Ergebnis hat die gleichen Auswirkungen wie das Entfernen des &
-Operators und das Ändern des []
-Operators in einen +
-Operator. Andernfalls ist das Ergebnis ein Zeiger auf ein Objekt oder eine Funktion, die vom Operanden festgelegt wird.
Beispiele
Im folgenden Beispiel werden diese gängigen Deklarationen verwendet:
int *pa, x;
int a[20];
Die Anweisung verwendet den address-of-Operator ( &
), um die Adresse des sechsten Elements des a
-Arrays abzurufen. Das Ergebnis wird in der Zeigervariable pa
gespeichert:
pa = &a[5];
Der Dereferenzierungsoperator (*
) wird in diesem Beispiel verwendet, um auf den Wert int
in der Adresse, die in pa
gespeichert ist, zuzugreifen. Der Wert wird der ganzzahligen x
-Variable zugewiesen:
x = *pa;
Dieses Beispiel zeigt, dass das Ergebnis der Anwendung des Dereferenzierungsoperators auf die Adresse von x
dasselbe wie bei x
ist:
assert( x == *&x );
In diesem Beispiel werden ähnliche Methoden zum Deklarieren eines Zeigers auf eine Funktion gezeigt:
int roundup( void ); /* Function declaration */
int *proundup = roundup;
int *pround = &roundup;
assert( pround == proundup );
Sobald die Funktion roundup
deklariert ist, werden zwei Zeiger auf roundup
deklariert und initialisiert. Der erste Zeiger proundup
wird unter ausschließlicher Verwendung des Namens der Funktion initialisiert, während der zweite Zeiger pround
den address-of-Operator bei der Initialisierung verwendet. Die Initialisierungen entsprechen sich.