Zum Inhalt springen

C Pointer auf Pointer


sayso

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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).

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

*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

Link zu diesem Kommentar
Auf anderen Seiten teilen

"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...

:( :( :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...