[Frage] C-String (Zeiger auf Zeiger)
-
Hallo liebe Community
Zu dem Thema Zeiger auf Zeiger bei den C-Strings erscheint mir etwas noch unklar.
Beispiel
char *carray[3] = {"String1", "String2", "String3"}; /* carray[0] == *carray == "String1" carray[1] == *(carray+1) =="String2" carray[2] == *(carray+2) =="String3" carray[0][0] == **carray == 'S' carray[1][0] == **(carray+1) == 'S' carray[2][1] == *(*(carray+2)+1) == 'S' */
Ich weiss das der Zeiger *carray die Adresse des "Arrays vom Typ Charakter" enthält. Was ich nicht genau verstehe ist (bei den C-Strings :S) haben wir noch den Zeiger **carray, welcher auf den Zeiger *carray zeigt und der wiederrum auf den C-String selber?? Und wen *carray ja "String1" in meinem Beispiel ausgibt, und der Zeiger welcher auf den *carray zeigt schlussendlich dereferenziert auch auf das gleiche zeigt, wieso gibt dieser nicht "String1" raus sondern 'S'? Liegt das daran das er nur das Erste belegte Byte zeigt?
Die Schreibweisse an sich ist mir klar, jedoch nicht das ganze Prinzip mit dem Zeiger auf den Zeiger, für eine Antwort wäre ich sehr dankbar
-
Ein C-String ist letztlich nur ein Array von Zeichen (mit einem '\0' am Ende). dein
char* carray[3]
ist ein Array von drei Zeigern, die jeweils auf so ein Zeichen-Literal verweisen.
(und in C++ wird ein Array bei fast jeder Gelegenheit umgewandelt in einen Zeiger auf sein erstes Element)
-
Danke für deine Antwort.
Ich denke jetzt verstehe ich das. Durch den Zeiger, wird auf das erste Element gezeigt, wird dem angewiesen ein Speicherblock weiter zu zeigen geht er genau um 1Byte weiter und der Array selber (carray[3]) springt jeweils zu einem Zeichen-Literal und geht das bis zum Terminierungszeichen ('\0') durch.
-
arb3r schrieb:
Ich denke jetzt verstehe ich das. Durch den Zeiger, wird auf das erste Element gezeigt, wird dem angewiesen ein Speicherblock weiter zu zeigen geht er genau um 1Byte weiter
Nicht ganz - der Zeiger weiß, wie groß der dahinterliegende Datentyp ist, und springt entsprechend weit, wenn er erhöht ist.
In deinem Array sind auch wieder Zeiger und wenn du diese dereferenzierst, landest du bei den String-Literalen, durch die du dann auch durchlaufen kannst.
-
Wie ist das dan bei diesem Beispiel...
char carray[3] = {'a', 'b', 'c'}; cout << carray[0];
Wen ich hier carray[0] ausgebe, wird hier auch das Terminierungszeichen eingesetzt?
-
Nein, ein einzelnes Zeichen hat keinen Null-Terminator (dein Array übrigens auch nicht *). Die Ausgabe-Operatoren wissen aber, wie sie mit verschiedenen Datentypen umgehen müssen: Bei einem char wird nur dessen Wert ausgegeben, bei einem char-Array/Zeieger alle Zeichen von der Zielposition bis zum Stringende (Null-Terminator).
* das Array enthält wirklich nur die drei angegebenen Zeichen, damit ist es ungeeignet für alle Funktionen, die mit C-Strings arbeiten wollen.
-
Nein wird es nicht, du erhälst so nur ein char, nämlich das 'a'.
Ein Stringliteral beinhaltet automatisch immer das abschließende Nullzeichen( "String" ), ein einzelnes char( 's' ) beinhaltet dies nicht.Lg freeG
Edit: Sorry zu langsam...
-
Vielen Dank für eure Hilfe...
-
arb3r schrieb:
char *carray[3] = {"String1", "String2", "String3"}; /* carray[0] == *carray == "String1" carray[1] == *(carray+1) =="String2" carray[2] == *(carray+2) =="String3" carray[0][0] == **carray == 'S' carray[1][0] == **(carray+1) == 'S' carray[2][1] == *(*(carray+2)+1) == 'S' */
Die letzte Zeile des Kommentars ist falsch. Da müsste ein 't' stehen.