Adresse eines char-Arrays ausgeben



  • die Adressen eines numerischen Arrays können ja wie folgt ermittelt werden:

    int feld[4]={1,2,3,4};
    
    int *zfeld;  // Zeiger auf eine int Variable
    zfeld = feld; // oder zfeld = &feld[0]
    
    cout << feld     << endl; // Adresse des ersten Arrayelementes
    cout << &feld[0] << endl; // wie oben , weil feld = &feld[0]
    cout << zfeld    << endl; // wie oben,  weil wir dem Zeiger die Adresse
                              // von dem ersten Element von feld[4] zugewiesen haben
    
    cout<<feld+2;  /// Adresse des 3. Elements
    

    nur wie ermittle ich die Adressen eines char Arrays ?
    cout wird hier immer den Wert ausgeben. Wobei der Feldname ja immer noch die Adresse enthält.


  • Mod

    Das liegt daran, weil der Operator << eine Sonderbehandlung für char* hat. Caste den Zeiger einfach auf etwas anderes. Dies hier sollte funktionieren:

    char feld[4]={1,2,3,4};
     cout << static_cast<void*>(feld)     << endl;
    


  • rotondo schrieb:

    nur wie ermittle ich die Adressen eines char Arrays ?

    Prinzipiell genauso. Du musst nur den Zeiger vorher nach void* konvertieren, damit auch die Adresse ausgegeben wird und nicht die Zeichenkette, auf die der char-Zeiger zeigt.

    rotondo schrieb:

    cout wird hier immer den Wert ausgeben.
    Wobei der Feldname ja immer noch die Adresse enthält.

    Der Wert eines Zeigers ist die Adresse. Der Feldname enthält keine Adresse. Das Feld sitzt aber irgendwo im Speicher an einer bestimmten Adresse.

    SeppJ ist mir heute scheinbar 2-3 Minuten voraus. Wen nich auf Preview klicke, hat er seine Antwort schon drunter gesetzt. 🙂



  • Der Wert eines Zeigers ist die Adresse. Der Feldname enthält keine Adresse. Das Feld sitzt aber irgendwo im Speicher an einer bestimmten Adresse.

    Darf man sagen das der Name eines Arrays ein Zeiger auf das erste Element ist ?

    zum casten:

    hab grad folgendes probiert

    char feld[6]="Hallo";
    
    cout<<(int)feld;  // wird hier die Adresse des ersten Elements ausgegeben ?
    

    Aber mit (hex) bekomme ich keinen Hex Wert der Adresse



  • du hast mir ja die Lösung gegeben!! 🙂

    cout<<(void*)feld;
    

    aber was passiert hier genau und warum mit void ?


  • Mod

    rotondo schrieb:

    du hast mir ja die Lösung gegeben!! 🙂

    cout<<(void*)feld;
    

    aber was passiert hier genau und warum mit void ?

    Wie du schon festgestellt hast, verhalt sich der Name eines Arrays sobald man es an eine Funktion übergibt wie ein Zeiger auf das erste Element. Der Operator<< des Objekts cout ist so eine Funktion. Diese Funktion ist für allerlei verschiedene Typen überladen, unter anderem für void* und für char* . Rufst du den Operator<< mit dem Namen eines char-Arrays auf, so wird ein char* erkannt und die entsprechende Überladung benutzt. Die Funktion für char* gibt einen C-String aus.

    Wird irgendein anderer Zeiger an den Operator<< übergeben (oder äquivalent der Name eines Feldes eines anderen Typen als char[]), so gibt es erstmal keine genau passende Funktion die aufgerufen werden könnte. Aber es existiert eine implizite Konvertierung von allen Zeigertypen nach void* . Diese wird dann benutzt und es wird die Überladung für void* benutzt. Diese gibt die Adresse aus, auf die der übergebene Zeiger zeigt.

    willst du nun die Adresse eines char* ausgeben, so musst du irgendwie kenntlich machen, dass du die Überladung für void* benutzen willst und nicht die Überladung für char* . Dazu reicht es, den char* zu irgendeinen anderen Zeigertypen zu casten, in diesem Fall würde dieser andere Zeigertyp wieder zu void* konvertiert und die Überladung für void* benutzt. Man kann sich diese Indirektion aber auch sparen und direkt zu void* casten.



  • ROTONDO schrieb:

    Der Wert eines Zeigers ist die Adresse. Der Feldname enthält keine Adresse. Das Feld sitzt aber irgendwo im Speicher an einer bestimmten Adresse.

    Darf man sagen das der Name eines Arrays ein Zeiger auf das erste Element ist?

    Nein, darf man nicht, wenn man nichts falsch sagen will. Der Name eines Arrays ist ein "Lvalue-Ausdruck" desselben Array-Typs. Beispiel:

    int dings[5];
    

    dings bezeichnet einen Lvalue-Ausdruck vom Typ int[5]. Es gibt aber einen Mechanismus, derr sich "array-to-pointer-decay" nennt. Das heißt, dass wenn man den Namen als Initialisierer für etwas benutzt, was keine Referenz ist, findet automatisch eine Umwandlung zu einem Zeiger auf das erste Element statt:

    int *zeiger1 = dings;
    

    Trotzdem ist dings kein Zeiger. Das sieht nur so aus wegen der impliziten Umwandlung. Wenn dings ein Zeiger wäre, würde folgendes nicht mehr funktionieren:

    void foo(int (& array_referenz)[5]);
    
    void bar() {
      int arr[5];
      foo(arr);
    }
    

    Die Funktion foo bekommt eine Referenz auf ein 5-elementiges Array und keinen Zeiger.



  • Danke! Jetzt hab ich sogar Seppls Zeiger verstanden 🙂 Und da macht der void Zeiger auch wieder Sinn.


Anmelden zum Antworten