sayso Geschrieben 9. August 2006 Geschrieben 9. August 2006 Hallo Kollegen, ich habe mal wieder eine kleines Verständnisproblem und vllt. könnt ihr mir helfen... Es geht um folgenden Code: char c = 'x'; /* 1 */ char *p1; /* 2 */ char **p2 = &p1; /* 3 */ *p2 = &c; /* 4 */ *p1 = 'X'; /* 5 */ In Zeile 3 wird dem Zeiger auf einen Zeiger p2 die Adresse des Zeigers p1 zugewiesen somit referenziert p2 später auf das auf was p1 zeigt. Aber bei Zeile 4 habe ich ein Verständnisproblem. Ich habe doch "nur" einen Pointer auf einen Pointer mit char **p2 deklariert, wieso gibt es den "einfachen" Zeiger *p2 auch noch? und wieso kann ich mit *p1 dann die char variable c ändern... Vllt. kann mir das jemand von euch erklären. Für mich würde es sich nur so logisch erschliessen char c = 'x'; /* 1 */ char *p1 = &c; /* 2 */ char **p2 = &p1; /* 3 */ **p2 = 'X'; /* 4 */ Den Ursprungscode habe ich von http://c-faq.com/ansi/constmismatch.html Den Code habe ich mit den Typen vereinfacht, da der Code aus dem Link ein anderes Problem erklärt aber ich verstehe die Zuweisung einfach nicht... Hoffentlich könnt ihr licht ins dunkele bringen Danke Zitieren
Bubble Geschrieben 9. August 2006 Geschrieben 9. August 2006 Aber bei Zeile 4 habe ich ein Verständnisproblem. Ich habe doch "nur" einen Pointer auf einen Pointer mit char **p2 deklariert, wieso gibt es den "einfachen" Zeiger *p2 auch noch? und wieso kann ich mit *p1 dann die char variable c ändern... In der Zeile bekommt der Inhalt von p2 (vorangestelltes Sternchen) eine Adresse zugewiesen. Dies geht, da p2 ein Zeiger auf einen Zeiger darstellt, der Inhalt eines Zeigers auf einen Zeiger ist also ein Zeiger, der durch eine neue Adresse ersetzt wird. Da p1 auf den Inhalt von c Zeigt - es handelt sich also um den Speicherbereich von c -, wird duch eine Änderung des Speichersinhalts, auf den p1 zeigt, auch der Inhalt von c verändert. (*p1 und c sprechen den gleichen Speicherbereich an). Zitieren
sayso Geschrieben 9. August 2006 Autor Geschrieben 9. August 2006 In der Zeile bekommt der Inhalt von p2 (vorangestelltes Sternchen) eine Adresse zugewiesen. Dies geht, da p2 ein Zeiger auf einen Zeiger darstellt, der Inhalt eines Zeigers auf einen Zeiger ist also ein Zeiger, der durch eine neue Adresse ersetzt wird. Da p1 auf den Inhalt von c Zeigt - es handelt sich also um den Speicherbereich von c -, wird duch eine Änderung des Speichersinhalts, auf den p1 zeigt, auch der Inhalt von c verändert. (*p1 und c sprechen den gleichen Speicherbereich an). Sorry hab ich nicht verstanden *p2 ist aber nirgends deklariert, da ich doch nur **p2 deklariert habe. Gehen wir es mal so an: char c = 'x'; /* 1 */ char *p1 = NULL; /* 2 */ char **p2 = &p1; /* 3 */ *p2 = &c; /* 4 */ *p1 = 'X'; /* 5 */ Zeile 1 --> c = x (eigene speicheradresse 111) Zeile 2 --> zeiger p1 zeigt auf speicheradresse NULL (eigene speicheradresse 222) Zeile 3 --> zeiger auf zeiger p2 zeigt auf speicheradresse 222 (eigene speicheradresse 333) Zeile 4 --> ??? Zeile 5 --> ??? Trotzdem schonmal danke hmm Zitieren
Bubble Geschrieben 9. August 2006 Geschrieben 9. August 2006 *p2 ist aber nirgends deklariert, da ich doch nur **p2 deklariert habe. "p2" ist deklariert. (Was Dich evtl. irritiert ist, dass Variablennamen keinen Stern enthalten dürfen. Bei der Deklaration sagt ein Stern vor dem Namen nur aus, dass es sich um einen Zeiger auf eine Variable des angegebenen Typs handeln soll.) Wird einem (deklarierten) Zeiger, in diesem Fall p2, der Stern-Operator (Indirektions-Operator) vorangestellt, dann bedeutet dies, dass nicht auf den Inhalt von p2 (was eine Speicheradresse wäre), sondern auf den Inhalt der Speicheradresse, auf die der Inhalt von p2 zeigt, zugegriffen werden soll. Der *-Operator dereferenziert also in diesem Fall einen Zeiger. Beispiel: int a = 10; int *Zeiger = &a; // Es gilt nach der letzten Zuwesung a == *Zeiger // noch ist a == 10 *Zeiger = 0; // jetzt ist a == 0 bzw. *Zeiger == 0 Zitieren
sayso Geschrieben 10. August 2006 Autor Geschrieben 10. August 2006 "p2" ist deklariert. (Was Dich evtl. irritiert ist, dass Variablennamen keinen Stern enthalten dürfen. Bei der Deklaration sagt ein Stern vor dem Namen nur aus, dass es sich um einen Zeiger auf eine Variable des angegebenen Typs handeln soll.) Wird einem (deklarierten) Zeiger, in diesem Fall p2, der Stern-Operator (Indirektions-Operator) vorangestellt, dann bedeutet dies, dass nicht auf den Inhalt von p2 (was eine Speicheradresse wäre), sondern auf den Inhalt der Speicheradresse, auf die der Inhalt von p2 zeigt, zugegriffen werden soll. Der *-Operator dereferenziert also in diesem Fall einen Zeiger. Beispiel: int a = 10; int *Zeiger = &a; // Es gilt nach der letzten Zuwesung a == *Zeiger // noch ist a == 10 *Zeiger = 0; // jetzt ist a == 0 bzw. *Zeiger == 0 Hallo, das mit dem Beispiel ist ja klar. Der Zeiger int *Zeiger zeigt au den Speicherinhalt der Variable int a. Aber in diesem Beispiel: char c = 'x'; /* 1 */ char *p1 = NULL; /* 2 */ char **p2 = &p1; /* 3 */ *p2 = &c; /* 4 */ *p1 = 'X'; /* 5 */ Habe ich ja einen Zeiger auf einen Zeiger definiert. D.h. in Zeile 3 würde der Zeiger **p2 auf den Inhalt auf den Zeiger *p1 zeigt zeigen und somit (bis zu Zeile 3) auf NULL. Wieso allerdings dann der Zeiger *p1 auf char c zeigt ist für mich nicht navollziehbar, denn für mich wäre es nur logisch wenn folgendes passieren würde.. *p1 = &c; *p2 ist doch laut deklaration nur ein Zeiger und kein Zeiger auf einen Zeiger, wieso dann durch *p2 = &c auch der Zeiger *p1 richtig gesetzt wird ist nicht klar... :( Zitieren
Guybrush Threepwood Geschrieben 10. August 2006 Geschrieben 10. August 2006 Ich denke du siehst das komplett falsch. durch die Deklaration char **p2 hast du keine Zeigervariable mit Namen **p2 sondern die heißt p2. Die beiden Sterne bei der Deklaration sagen nur aus das es sich bei p2 um einen Zeiger auf einen Zeiger handelt. Später im Programm ist das * dann der Dereferenzierungsoperator. Das heißt in folgendem Beispiel: int i=15; int *p1=&i; p1 = 16 //1 *p1 = 16 // 2 [/PHP] An Stelle 1 würdest du den Zeiger p1 auf die Adresse 16 zeigen lassen An Stelle 2 aber dereferenzierst du den Zeiger und weißt somit dem Speicher auf den er zeigt (also i) 16 zu. Genau das selbe jetzt mit p2: [PHP] int i=15; int *p1=0; int **p2=&p1 //1 *p2=&i; //2 *p1 = 16; //3 **p2 = 16; //3 1) Du legst einen Zeiger auf einen Zeiger an der auf den Zeiger p1 zeigt 2) Du derefernzierst p2 einmal und weißt die Adresse von i zu. Das heißt p2 (also der Zeiger auf einen Zeiger) zeigt auf den Zeiger p1 welchen du so auf i zeigen lässt 3) Diese Zeilen machen bei vom Prinziep her das selbe. p1 zeigt auf i und somit wird durch die dereferenzierung i auf 16 gesetzt. p2 zeigt auf p1 das auf i zeigt und somit wird i durch die 2 fache dereferenzierung auch auf 16 gesetzt. Ich hoffe das wird dadurch etwas verständlicher. Zitieren
sayso Geschrieben 10. August 2006 Autor Geschrieben 10. August 2006 Ich denke du siehst das komplett falsch. Ich hoffe das wird dadurch etwas verständlicher. Ja da hattest du recht ich habe das komplett falsch gesehen... Das war perfekt erklärt, nun hab ichs auch verstanden :nett: :e@sy danke... Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.