Warum enthält der Zeiger diese Daten (c++)?

3 Antworten

Also, ich versuche mal zu erklären, was hier passiert und markiere die verschiedenen Stellen im Speicher mit (a), (b) und (c):

1) Du legst den Pointer "liste" an, der auf die Speicherstelle eines neuen Listenelements zeigt:

liste ---> (a)

2) Du legst den Pointer "hilfszeiger" an, der auf die Speicherstelle eines neuen Listenelements zeigt:

hilfszeiger ---> (b)

3) Du setzt an der Speicherstelle (a) die Variable "daten" auf "Element 1":

(a)->daten = "Element 1"

4) Du verbiegst "hilfszeiger" auf Speicherstelle der "liste", Speicherstelle (b) wird somit nicht mehr benutzt, beide Variablen sind quasi identisch:

liste ---> (a) <--- hilfszeiger

5) Du erzeugst für hilfszeiger->next ein neues Listenelement mit neuer Speicherstelle:

liste/hilfszeiger ---> (a)->next = (c)

6) Du setzt den "hilfszeiger" auf die Speicherstelle des next-Listenelements von "hilfszeiger", also auf (a)->next, was ja Speicherstelle (c) ist. Somit bleibt "liste" allein auf Speicherbereich (a):

hilfszeiger ---> (c)

liste ---> (a)

7) Du setzt "daten" von "hilfszeiger" auf "Element 2":

hilfszeiger ---> (c)->daten = "Element 2"

-----------------------------------------------------------------------------------------------------------

Ergebnis:

"hilfszeiger" zeigt auf Speicherstelle (c), das "Element 2" als "daten" beinhaltet

"liste" zeigt auf Speicherstelle (a), das "Element 1" als "daten" beinhaltet

Deine Ausgabe:

liste->next->daten

bedeutet also:

(a)->next = (c), und (c)->daten beinhaltet "Element 2"

Ich hoffe das war einigermaßen verständlich. Sollten Fragen verbleiben, dann einfach in die Kommentare damit.

Beste Grüße,
droeme


Also wenn ich mir liste->daten ausgeben lasse, bekomme ich Element 1 zurück.

cout << liste->next->daten << endl; bei der Ausgabe erhält man allerdings Element 2

0
@Jupitercrafter

Ja natürlich.

Erst setzt du die Variable hilfszeiger, der Zeiger soll auf das gleiche Objekt im Speicher zeigen, wie es die Variable liste tut:

hilfszeiger = liste;

Dann schnappst du dir das Element next und lässt den Zeiger darauf refefenzieren:

hilfszeiger = hilfszeiger->next;
1
@regex9

Ok vielen Dank, also hilfszeiger und liste zeigen auf das gleiche objekt im Speicher, das heißt wenn ich im weiteren verlaufe des Code die liste verändere, verändert sich auch der hilfszeiger?


Und ich habe ein etwas komplexere Aufgabe programmiert, handelt es sich hierbei um das gleiche? Hier wird der hilfszeiger mit dem listenanfang gleichgesetzt und ich kann über 

listenanfang->next->daten auf Element 2 zugreifen. Bei der Ausgeben Funktion steht 

Element 1

Element 2

Element 3

Element 4

Vielen Dank im Voraus :)


#include
using namespace std;

struct listenelement
{
string daten;
listenelement* next;
};

listenelement* anhaengen(string datenneu, listenelement* listenende)
{

//ein neues Element an das Ende der Liste anhängen
listenende->next = new(listenelement);
//den Hilfszeiger auf das neue Element setzen
listenende = listenende->next;
//die Daten in das neue Element eintragen
listenende->daten = datenneu;
//es gibt keinen Nachfolger, daher wird next auf NULL gesetzt
listenende->next = nullptr;
//Zeiger vom letzten Element zurückgeben
return listenende;
}

void ausgeben(listenelement *listenanfang)
{
//Ein lokaler Hilfszeiger, um in der Liste wandern zu können
listenelement* hilfszeiger;
//den Hilfszeiger auf den Anfang der Liste setzen
hilfszeiger = listenanfang;
//das erste Element ausgeben
cout << hilfszeiger->daten << '\n';
//Solange das Ende der Liste noch nicht erreicht ist:
while (hilfszeiger->next != nullptr)
{
//den Hilfszeiger hilfszeiger auf das nächste Element setzen
hilfszeiger = hilfszeiger->next;
//Daten ausgeben
cout << hilfszeiger->daten << '\n';
}
}

void ende(listenelement* listenanfang)
{
//Ein lokaler Hilfszeiger, um in der Liste wandern zu können
listenelement* hilfszeiger;
//Solange noch Elemente in der Liste sind
while (listenanfang != nullptr)
{
//den Hilfszeiger auf das erste Element der Liste
hilfszeiger = listenanfang;
//den Zeiger für den Listenanfang auf das nächste Element setzen
listenanfang = listenanfang->next;
//den Speicher für das herausgenommene Element freigeben
delete(hilfszeiger);
}
}

int main()
{
//ein Zeiger auf den Anfang der Liste
listenelement* listenanfang;
//das erste Element erzeugen
listenanfang = new(listenelement);
//Daten in das erste Element schreiben
listenanfang->next = nullptr;
listenanfang->daten = "Element 1";

listenelement* hilfszeiger;
hilfszeiger = listenanfang;

//und jetzt weitere Elemente erzeugen
hilfszeiger = anhaengen("Element 2", hilfszeiger);
hilfszeiger = anhaengen("Element 3", hilfszeiger);

hilfszeiger = anhaengen("Element 4", hilfszeiger);


ausgeben(listenanfang);
ende(listenanfang);


return 0;
}

0
@Jupitercrafter

(...) das heißt wenn ich im weiteren verlaufe des Code die liste verändere, verändert sich auch der hilfszeiger?

Grob gesagt ja. Genau erklärt natürlich nicht - die beiden Variablen beinhalten einfach nur eine Adresse, die auf ein Objekt im Speicher zeigt. Über die beiden Variablen kann das referenzierte Objekt angesprochen und geändert werden. An sich ändert sich nur das Objekt, die Referenzen / Adressen hingegen bleiben konstant.

Ein bildliches Beispiel könnte folgendes sein: Es gibt eine Mietwohnung mit Mieter (dem Objekt), dessen Adresse dem Vermieter und einem Verwandten des Mieters (Zeigervariablen) bekannt ist. Beide haben also irgendwie Zugriff auf den Mieter. Wenn der Vermieter den Mieter rausschmeißt, kennt der Verwandte zwar immer noch die gleiche Adresse, doch hat sich das Objekt dahinter verändert, der Mieter ist nicht mehr da.

Wenn du deinen Code etwas umänderst, kannst du das Verhalten ebenso einfach reproduzieren:

#include <iostream>
using namespace std;

struct listenelement
{
    string daten;
    listenelement* next;
};

int main(){
   listenelement* liste = new(listenelement);
   liste->daten = "Hallo";
   cout << liste->daten << endl; // Hallo
	
   listenelement* hilfszeiger = liste;
   cout << hilfszeiger->daten << endl; // Hallo
	
   hilfszeiger->daten = "Welt";
   cout << liste->daten << endl; // Welt
   cout << hilfszeiger->daten << endl; // Welt
	
   return 0;
}

(...) handelt es sich hierbei um das gleiche? (...)



Wenn du einem Zeiger einen anderen Zeiger zuweist, zeigen beide auf das Gleiche. Lies dazu bitte Artikel / Dokumentationsseiten, die sich mit dem Thema Zeiger näher beschäftigen. Z.B.:

https://de.wikibooks.org/wiki/C%2B%2B-Programmierung/\_Weitere\_Grundelemente/\_Zeiger

0

Wo hat der Code eine Ausgabe?

Entschuldigung: cout << liste->next->daten << endl;

0

Was möchtest Du wissen?