Adresse &

Mittels des Adress-Operators kann auf die Speicheradresse einer Variablen oder eines Elementes zugegriffen werden. Das AND-Zeichen & steht dabei links des Ausdruckes, zu welchem die Adresse ausgewertet werden soll.






Address of a: bffff89c
Address of b: bffff898
#include <stdio.h>

int main(){
  int a = 5;
  int b = 5;
  printf("Address of a: %x\n", (unsigned int)&a);
  printf("Address of b: %x\n", (unsigned int)&b);
  return 0;
}

Siehe auch Dereferenz-Operator *

Details

Der Adress-Operator erwartet einen Operanden als lvalue und wird von rechts nach links abgearbeitet. Der Rückgabewert ist ein rvalue und hat als Typ einen Pointer auf den Typ des Operanden.

Der Adress-Operator ist das direkte Gegenstück zum Dereferenz-Operator. Während der Adress-Operator zu einem lvalue den Pointer zurückgibt, wandelt der Dereferenz-Operator ebendiesen Pointer wieder zurück in einen lvalue.

Der Adress-Operator kann für beliebige Ausdrücke verwendet werden, welche zu einem lvalue auswerten, der sich im Speicher befindet. Dieser Operator funktioniert somit insbesondere für Variablen, aber auch für Elemente von struct-, class- oder Array-Typen.











Address: bffff89c
Address: bffff88c
#include <stdio.h>

struct BMI{
  float weight;
  float height;
};

int main(){
  struct BMI a = {65, 1.75};
  int b[5] = {1, 2, 3, 4, 5};
  printf("Address: %x\n", (unsigned int) &(a.height));
  printf("Address: %x\n", (unsigned int) &(b[2]));
  return 0;
}

Man beachte hierbei, dass die Klammern aufgrund der Operatorenrangordnung nicht nötig wäre, der Lesbarkeit halber jedoch werden sie hier geschrieben (nach Gutdünken des Autors).

Dieser Operator wird häufig verwendet, wenn eine Funktion ein Pointer-Argument erwartet, das gewünschte Argument beim Funktionsaufruf jedoch nur als Referenz vorliegt. Gerade in den Standardbibliotheken gibt es einige Funktionen, welche einen Pointer auf eine Variable erwarten, insbesondere um den dadurch adressierten Wert auch in der aufrufenden Funktion zu verändern. Weitere Informationen darüber können bei den Argumenten und Parametern nachgelesen werden.

Wenn bei einer Register-Variablen versucht wird, mittels des Adress-Operators & die Adresse anzusprechen, meldet der Compiler den Fehler address of register variable ... requested.

Überladen des Operators

Die semantische Bedeutung des Adress-Operators ist das Ansprechen der Speicheradresse eines lvalues. Mittels der Operatoren-Überladung kann diese Information grundsätzlich beliebig interpretiert werden und es wären gewisse Konstrukte denkbar, die einen sogenannten smart pointer speichern, welche bei Aufruf des Adress-Operators automatisch die Adresse der referenzierten Daten zurückgeben.

Durch das Definieren eines selbst-gebastelten Adress-Operators übernimmt jedoch der Programmierer die Verantwortung der korrekten Speicherung und Ansprechung der Daten. Dadurch wird es einem aussenstehenden Programmierer oder auch nur schon den Funktionen der Standardbibliotheken unmöglich, ein genormtes Verhalten von Klassen zu erwarten und es können seltsame Effekte auftreten, deren Fehler weitreichend sein können. Das Pointer-Konzept von C und C++ sowie die Anordnung von Variablen im Speicher ist nach Meinung des Autors so fundamental, dass von der Überladung des Adress-Operators in irgendwelcher Art abgeraten wird. Dennoch hier für den interessierten Leser die üblichen Kommentare zur Überladung des Adress-Operators:

Die Prototypen für das Überladen des Adress-Operators sind die folgenden (Einschränkungen und Erläuterungen siehe Überladen von Operatoren):

inside class


outside class
Type operator &();
Type operator &() const;

Type operator &(Type);

Der Autor sieht in der Überladung des Adress-Operators grundsätzlich keinen Sinn und bastelt sich hiermit der Einfachheit halber einen Null-Pointer:










Address of s: 0
#include <cstdio>

class Something{
public:
  Something* operator&() const {return NULL;}
};

int main(){
  Something s;
  printf("Address of s: %x\n", (unsigned int) &s);
}