char und char*



  • Der Typ "char" kann ja nur ein Zeichen speichern:

    char test = 'C';

    Warum kann dann ein char-Zeiger mehrere Zeichen speichern?

    char* test = "Haha";

    Hmm, worauf Zeigt test nun eigentlich? test ist ja kein Vektor, daher wird nicht auf "H", also 1. Stelle gezeigt oder?

    Das verwirrt..



  • Verwirrter schrieb:

    Hmm, worauf Zeigt test nun eigentlich? test ist ja kein Vektor, daher wird nicht auf "H", also 1. Stelle gezeigt oder?

    Auch wenn's wirklich kein Vektor (was meinst du damit überhaupt?) ist, er zeigt tatsächlich nur auf's "H".



  • char name[4] = "Haha";
    

    Das meine ich mit Vektor.
    Nun ist "name" ein Zeiger auf das 1. Element.

    Aber warum wird hier alles ausgegeben?

    char* test = "Haha"; 
        cout << test;
    

    😕

    Warum kann ein Zeiger mehrere Zeichen speichern...



  • Hallo

    char * ist ein Sonderfall.
    Nicht umsonst ist das als Null-Terminierter C-String bezeihnet.
    Denn mit deiner Anweisung

    char* test = "Haha";
    

    erzeugst du effektiv diese Zeichenkette "Haha\0". Deshalb must du bei dynamischer Char-Erstellung auch immer ein SPeicherplatz mehr reservieren als du Nutzzeichen brauichst... für das abschließende '\0'.
    Das ist das Terminierungszeichen. String-Funktionen lesen C_Strings immer bis zum abschließenden Terminierungszeichen.

    bis bald
    akari



  • Ja das weiß ich schon, ich dachte nur, char kann immer nur EIN Zeichen speichern.

    Denn ich hatte mir gerade Zeigervektoren angesehen, da wunderte es mich als ich das sah:

    char* error[] = { "Ungültig", "Fehler 1: ", "Fehler 2: " };

    Das wären dann ja mehrere char-Zeiger, und ich dachte die können ja nur 1 Zeichen speichern...



  • Ja, char kann nur 1 Zeichen speichern. char* ist ein Zeiger (auf char) und Zeiger enthalten bekanntlicherweise Adressen. Also zeigt dein char-Zeiger auf den Anfang der Adresse, wo der String "Haha" hinterlegt ist (also auf das 'H'). Da in char-Arrays nicht die Anzahl der Zeichen gespeichert ist, muss es eine Endekennung für eine Zeichenfolge geben und das ist die Null ('\0').

    Was mir beim verstehen von Zeigern gut geholfen hat, war Assembler. Das hat mir persönlich einiges erleichtert beim Umgang und beim Verstehen von Zeigern.



  • Aha..

    Assembler möchte ich vorerst nicht lernen.

    Aber du kannst mir Zeiger ruhig genau erklären, aber ich wüsste nicht was man mehr wissen muss als:

    -Zeiger sind ein eigenes Objekt im Speicher
    -Zeiger zeigen auf die Adresse eines anderen Objekts

    ..



  • Dann sollte doch eigentlich alles klar sein. 😉



  • Hmm eins versteh ich immer noch nicht ganz...

    // Warum muss man keinen Adressoperator voransetzen?
        char* b = "Haha";
    
        // Zum Vergleich...
        int* p = &a;
    

    Und warum ist dann *b gleich "H" und b bei der Ausgabe der ganze String

    b ist doch das Zeigerobjekt welches auf die Adresse verweist
    und *b zeigt doch auch auf die Adresse...

    😕



  • Weil a eine Variable ist. "Haha" ist eine statisch hinterlegte Zeichenkette, dass wandelt der Compiler dann schon alles entsprechend um. *b bedeutet das du den Zeiger dereferenzierst und d.h., da er auf den Anfang der Zeichenkette zeigt, kommt dabei das 'H' raus.

    void charOut(char *p) {
      while(*p != '\0') {
        cout << *p << endl;
        ++p;
      }
    }
    

    Wenn du jetzt einen C-String an diese Funktion übergibst, wird es dir zeigen, dass p immer auf die nachfolgende Adresse zeigt, wo immer ein Zeichen bei rauskommt, wenn du es dereferenzierst. Wenn du in der Zeile mit der Ausgabe, dies schreiben würdest:

    cout << p << endl;
    

    Würde der String immer um 1 Zeichen kürzer werden.
    b enthält die Adresse auf ein Zeichen und *b ist das Zeichen an der Adresse in b. Warum "cout << p;" den gesamten String ausgibt, hängt an damit zusammen das der operator<< entsprechend überladen wurde. Es könnte genauso gut die Adresse von b ausgegeben werden, was aber doch etwas unhandlich wäre. Wenn man die Adresse haben will, kann man immer noch einen entsprechenden Cast verwenden.

    Vielleicht solltest dir mal das hier ansehen und versuchen ohne Compiler zu lösen ;):
    http://www.fh-wedel.de/~si/vorlesungen/c/felderUndZeiger/zeigersalat.html



  • Achsoo, man sollte besser unabhängig von der Standardausgabe versuchen sowas zu verstehen 😞

    "b enthält die Adresse auf ein Zeichen und *b ist das Zeichen an der Adresse in b"

    Jetzt ists mir klar 😃

    Was ist denn das für ein Salat?? Was ist das für ein Operator -> "***" ?


Anmelden zum Antworten