Verständnisfrage zu char zeiger



  • Also, vermutlich langweilen euch solche Fragen, aber mein Buch konnte mir keine Erklärung liefern und die Frage ist zu spezifiscvh um zu googlen...

    char *zeiger;
    zeiger = "ABC";
    

    Warum geht das? Ich dachte Zeiger speichern nur adressen und um nen wert zu belegen muss man dereferenzieren...Außerdem scheint das nur mit char-zeigern zu klappen.

    Bei

    int *zeiger = 12;
    

    erhält man ne Fehlermeldung "invalid conversion from int to *int", was ja auch sinnvoll ist...



  • "ABC" ist kein char, sondern ein char[4], das implizit in einen char * propagiert wird. Deshalb klappt die Zuweisung. Wenn auch oft nur mit einer Warnung, dass man ein String-Literal besser einem const char * zuweisen sollte.

    Stefan.



  • okay, das heißt, wenn ich das richtig verstehe, dass der zeiger auf ein array zeigt, oder auf den anfang des arrays, wenn ich mich recht entsinne, aber wenn ich den code alleinstehend benutze, hab ich dem "ABC" noch gar nichts außer diesem zeiger zugeordnet. Ich kann es, sollte ich den Zeiger neu ausrichten, nie wieder ansprechen, eine zuweisung machen, etc.

    Es wäre dann futsch.

    Sehe ich das richtig?



  • Du hast dem Zeiger die Adresse von "ABC" zugewiesen. "ABC" kannst du nichts zuweisen. Wenn du den Zeiger überschreibst, sagen wir mal mit Zeiger = "hallo" oder Zeiger = 0, dann kommst du an "ABC" nicht mehr ran, es sei denn es gibt noch einen anderen Zeiger der da hinzeigt.



  • Sorry, ich meinte auch, dass ich einem wert "ABC" zuweise und nicht andersrum.



  • kARRE schrieb:

    Sorry, ich meinte auch, dass ich einem wert "ABC" zuweise und nicht andersrum.

    Einem Wert kann man nichts zuweisen.



  • ihr wisst, was ich meine (deutsche sprache - schwere sprache...und mitten in der nacht geschrieben)



  • kARRE zu besuch schrieb:

    deutsche sprache - schwere sprache...

    Das heißt "deutsches Sprache, schweres Sprache"! 😉



  • kARRE zu besuch schrieb:

    ihr wisst, was ich meine (deutsche sprache - schwere sprache...und mitten in der nacht geschrieben)

    Ich weiß das jedenfalls nicht. Entweder verwendest Du die Begriffe falsch oder hast Probleme mit der deutschen Grammatik. Hellsehen kann ich nicht.



  • Ich habe dein Problem eigentlich auch nicht verstanden, versuche aber trotzdem mal eine Erklärung.

    Wenn du in deinem Programm etwas wie "ABC" schreibst, ist das ein String-Literal (eine String-Konstante) mit dem Typ char-Array, im Beispiel also char[4]. Dieses String-Literal kannst du wie einen char * verwenden (besser wie einen const char *), also klappt deine Zuweisung zeiger = "ABC". zeiger zeigt jetzt auf das erste Element des char-Arrays "ABC".

    kARRE schrieb:

    Ich kann es, sollte ich den Zeiger neu ausrichten, nie wieder ansprechen, eine zuweisung machen, etc.

    Falls du damit meinst, dass du ein Speicherleck hast, stimmt das nicht. Das liegt an der Art und Weise, wie solche String-Literale vom Compiler erstellt werden. Sie werden nämlich im "Datensegment" des Programms angelegt (zumindest unter Windows) und nicht auf Heap oder Stack. Vergleiche:

    foo() {
    
       char *str1 = new char[4];
       std::strcpy(str1, "ABC");
       str1 = "XYZ";   // Hier entsteht ein Speicherleck
    
       char *str2 = "ABC";
       str2 = "XYZ";   // Hier entsteht kein Speicherleck
    }
    

    Der Speicher, auf den str1 zunächst zeigt, wird mit new(), also auf dem Heap erzeugt. Durch die spätere Zuweisung geht die Adresse des Speicherbereichs verloren, also hast du ein Speicherleck.

    Der Speicher, auf den str2 ursprünglich zeigt, liegt im Datensegment des Programms. Durch die spätere Zuweisung eines anderen Strings ändert sich natürlich die Adresse, aber ein Speicherleck entsteht nicht.

    Beantwortet das deine Frage?

    Stefan.



  • Sebastian Pizer schrieb:

    kARRE zu besuch schrieb:

    ihr wisst, was ich meine (deutsche sprache - schwere sprache...und mitten in der nacht geschrieben)

    Ich weiß das jedenfalls nicht. Entweder verwendest Du die Begriffe falsch oder hast Probleme mit der deutschen Grammatik. Hellsehen kann ich nicht.

    3. oder du hast zuviel theoretische Informatik studiert... ^^

    Also jeder, der ihn verstehen will, weiß ungefähr was er gemeint hat... Wenn man natürlich päpstlicher als der Papst ist, dann versteht man das nicht. 😉


  • Mod

    It0101 schrieb:

    Also jeder, der ihn verstehen will, weiß ungefähr was er gemeint hat... Wenn man natürlich päpstlicher als der Papst ist, dann versteht man das nicht. 😉

    Also ich habe in meinem Leben noch keine einzige Vorlesung Hochschulinformatik gehört und verstehe ihn trotzdem nicht. Ich vermute aber dass sich sein Problem von alleine lösen würde, wenn er sich nur genug mit dem Thema beschäftigen würde um überhaupt eine verständliche Frage stellen zu können.



  • kARRE schrieb:

    Warum geht das? Ich dachte Zeiger speichern nur adressen und um nen wert zu belegen muss man dereferenzieren...Außerdem scheint das nur mit char-zeigern zu klappen.

    // Jepp, Zeiger speichern Adressen:
       char* a = "ABC"; // a speichert die Adresse der Zeichenkette "ABC"
       char* b = "DEF"; // b speichert die Adresse der Zeichenkette "DEF"
       // Jepp, "um den Wert zu belegen", muss man dereferenzieren.
       // Funzt jedoch nicht beim obigen Datentypen.
       // Man kann jedoch durch dereferenzieren die einzelnen Zeichen lesen:
       cout << *a << *(a+1) << *(a+2) << endl;
    
       // Bei diesem Datentypen kann man durch dereferenzieren Werte belegen:
       char aa[] = "ABC";
       cout << *aa << *(aa+1) << *(aa+2) << endl;
       // Wir belegen mal den zweiten Buchstaben mit einem 'X':
       *(aa+1) = 'X';
       cout << *aa << *(aa+1) << *(aa+2) << endl; // Belegter String ;)
       // Statt belegen sagt man im allgemeinen: den Wert einer Variable ändern.
    

    mfg,
    F.d.S.


Anmelden zum Antworten