lempy Geschrieben 21. Dezember 2011 Geschrieben 21. Dezember 2011 (bearbeitet) Hallo Leute, Bin neu hier und mache nebenbei einen Fernlehrgang in C++/CLI. Hauptberuflich bin ich momentan Umschüler und habe für das Programmieren etwas weniger Zeit. Habe mein Heftchen durchgearbeitet und habe da zu der ersten Hausaufgabe ein paar Fragen. Diese Aufgabe wurde hier schon mal aufgegriffen, aber aus dem Jahr 2009. Ich muss ein neues Hilfshandle erstellen, dass nicht mehr den Listen Anfang sondern das Listen Ende an main() übergibt. Hier erst mal mein Code, der soweit funktioniert: // Einsendeaufgabe 5.1.cpp: Hauptprojektdatei. #include "stdafx.h" using namespace System; ref struct listenelement { String ^daten; listenelement ^next; }; // neues Element am Ende der Liste anhängen Void anhaengen (String ^datenneu, listenelement ^listenanfang) { // ein Hilfshandle zum Wandern in der Liste listenelement ^hilfsHandle; // HilfsHandle an den Anfang der Liste setzen hilfsHandle = listenanfang; // Hilfshandle zum Speichern des Vorgängers listenelement ^listenende; // Durch die Liste gehen, bis das letzte Element erreicht ist while (hilfsHandle -> next != nullptr) { hilfsHandle = hilfsHandle -> next; } // Aktuelle Adresse im Listenende speichern listenende = hilfsHandle; // Neues Element am Ende der Liste anhängen hilfsHandle -> next = gcnew listenelement; // Hilfshandle auf das neue Element setzen hilfsHandle = hilfsHandle -> next; // Vorgänger in letzte Adresse speichern //hilfsHandle -> ende = listenende; // Zeichenkette im neuen Element eintragen hilfsHandle -> daten = datenneu; // nullptr wird automatisch zugewiesen! } // Alle Elemente der Liste ausgeben Void ausgeben (listenelement ^listenanfang) { // ein Hilfshandle zum Wandern in der Liste listenelement ^hilfsHandle; hilfsHandle = listenanfang; // erstes Element ausgeben Console::WriteLine("{0}", hilfsHandle -> daten); // Solange das Ende der Liste noch nicht erreicht ist: // hilfshandle auf das nächste Element setzen und die Daten ausgeben while (hilfsHandle -> next != nullptr) { hilfsHandle = hilfsHandle -> next; Console::WriteLine("{0}", hilfsHandle -> daten); } } int main(array<System::String ^> ^args) { // Handle auf den Anfang der Liste listenelement ^listenanfang; //listenelement ^listenende; // das erste Element per Hand erzeugen listenanfang = gcnew listenelement; // Zeichenkette in das erste Element schreiben // nullptr wird automatisch gesetzt listenanfang -> daten = "Element 1"; // in einer Schleife mehrere Elemente einfügen for (Int32 schleife = 2; schleife < 4; schleife++) anhaengen("Element " + schleife, listenanfang); // die Liste ausgeben ausgeben(listenanfang); Console::Read(); return 0; } Jetzt meine Fragen: Normalerweise werden Variablen doch mit return an main weiter gegeben, oder? Void übergibt doch eigentlich keine Werte. Warum, funktioniert dieser Code? Läuft das bei verketteten Listen etwas anders? Habe schon in meinen zusätzlichen Büchern versucht was zu finden, aber das war eher verwirrend, weil der dort enthaltende Code wohl eher für Fortgeschrittene verständlich ist als für einen Anfänger. Währe nett, wenn mir einer von Euch erklären kann, wie das mit der Übergabe von Werten bei verketteten Listen Funktioniert. Lieben Dank lempy Bearbeitet 21. Dezember 2011 von Klotzkopp Zitieren
Klotzkopp Geschrieben 21. Dezember 2011 Geschrieben 21. Dezember 2011 Die Liste existiert nicht als einzelne Variable, sondern entsteht aus der Verknüpfung von mehreren Objekten. Es wird daher auch nirgends die Liste übergeben. Übergeben wird ein Zugriffsobjekt, in diesem Fall der Verweis auf den Listenanfang. Ein etwas hinkender Vergleich aus dem realen Leben: Wenn du ein Auto mietest, wird auch nicht das Auto über die Theke geschoben, sondern ein Schlüssel, der dir Zugriff auf das Auto gibt. Da dieser Veweis selbst nicht verändert wird (er zeigt nach dem Aufruf auf dasselbe Objekt, allenfalls wurde dessen Inhalt verändert), muss auch nichts zurückgegeben werden. Zitieren
lempy Geschrieben 22. Dezember 2011 Autor Geschrieben 22. Dezember 2011 (bearbeitet) Hallo Klotzkopp erstmal lieben Dank für Deine Antwort. Also kann ich davon ausgehen, dass die Angabe in der Hausaufgabe "***, dass das Listenende nach jedem Anhängen ermittelt wird und auch an die Funktion main() zurückgeliefert wird." nicht wie bei Variablen passiert. Habe hier noch einmal nur die Funktion anhaengen() kopiert und dazu noch ein paar Verständnis Fragen. Void anhaengen (String ^datenneu, listenelement ^listenanfang) { // ein Hilfshandle zum Wandern in der Liste listenelement ^hilfsHandle; // HilfsHandle an den Anfang der Liste setzen hilfsHandle = listenanfang; // Hilfshandle zum Speichern des Vorgängers [COLOR="green"]listenelement ^listenende; [/COLOR][COLOR="blue"]// Deklaration des Zeigers Listenende[/COLOR] // Durch die Liste gehen, bis das letzte Element erreicht ist while (hilfsHandle -> next != nullptr) { hilfsHandle = hilfsHandle -> next; } // Aktuelle Adresse im Listenende speichern [COLOR="green"]listenende = hilfsHandle; [/COLOR][COLOR="blue"]// Hier wird dem Hilfhandle das Listende zugewiesen? [/COLOR] // Neues Element am Ende der Liste anhängen [COLOR="green"]hilfsHandle -> next = gcnew listenelement;[/COLOR] [COLOR="blue"]// Neue daten an das Listenende anhängen und weil HilfsHandle jetzt listenende zugewiesen am Ende?[/COLOR] // Hilfshandle auf das neue Element setzen [COLOR="green"]hilfsHandle = hilfsHandle -> next;[/COLOR] [COLOR="blue"]// Weil Listenhandle hilfsHandle zugewiesen wurde zeigt der Zeiger jetzt an das Ende[/COLOR] // Zeichenkette im neuen Element eintragen hilfsHandle -> daten = datenneu; // nullptr wird automatisch zugewiesen! } Reicht in der Funktion main() wirklich nur der Zeiger ^listenanfang oder müsste ich noch einen für ^listenende haben? und sind meine Anmerkungen richtig? Wenn nicht, dann bitte ich Euch mich zu verbessern. Dann habe ich noch ne zweite Aufgabe, aber die kommt erst, wenn diese zu meiner Zufriedenheit gelöst ist. Danke lempy Bearbeitet 23. Dezember 2011 von Klotzkopp Zitieren
Klotzkopp Geschrieben 23. Dezember 2011 Geschrieben 23. Dezember 2011 Also kann ich davon ausgehen, dass die Angabe in der Hausaufgabe "***, dass das Listenende nach jedem Anhängen ermittelt wird und auch an die Funktion main() zurückgeliefert wird." nicht wie bei Variablen passiert. Doch, du sollst vermutlich das Listenende als listenelement^ an main zurückgeben. Der ^, der ein Handle auf den Managed Heap kennzeichnet, gehört übrigens zum Typ, nicht zum Variablennamen. Es könnte fürs Verständis förderlich sein, wenn du also String^ datenneu und listenelement^ hilfshandle schreibst. Syntaktisch tut sich das nichts. [COLOR="green"]listenende = hilfsHandle; [/COLOR][COLOR="blue"]// Hier wird dem Hilfhandle das Listende zugewiesen? [/COLOR] Andersrum. Das Ziel einer Zuweisung steht links. Der Zeiger listenende wird umgebogen, so dass er auf dasselbe Objekt zeigt wie der Zeiger hilfsHandle. Da hilfsHandle zu diesem Zeitpunkt auf das letzte Listenelement zeigt, tut listenende das jetzt auch. [COLOR="green"]hilfsHandle -> next = gcnew listenelement;[/COLOR] [COLOR="blue"] // Neue daten an das Listenende anhängen und weil HilfsHandle jetzt listenende zugewiesen am Ende?[/COLOR] Nicht "weil". Es wird einfach ein neues Element angehängt. Der next-Zeiger des letzten Listenelements ist vorher null (darum ist es ja das letzte). [COLOR="green"]hilfsHandle = hilfsHandle -> next;[/COLOR] [COLOR="blue"]// Weil Listenhandle hilfsHandle zugewiesen wurde zeigt der Zeiger jetzt an das Ende[/COLOR]Versteh ich nicht. hilfsHandle wird ein Objekt "weiter" gesetzt. Somit zeigt hilfsHandle auf das neue, eben erstellte Objekt, damit man hinterher die Daten eintragen kann. listenende zeigt unverändert auf das "alte" letzte, jetzt vorletzte Listenelement. Eigentlich brauchst du listenende gar nicht, der Zeiger wird nicht benutzt. Reicht in der Funktion main() wirklich nur der Zeiger ^listenanfang oder müsste ich noch einen für ^listenende haben?Ich denke, genau das ist die Aufgabe. Dafür brauchst du in anhaengen allerdings keine neue Variable, du musst nur den Rückgabetyp ändern und den passenden Wert zurückgeben. Zitieren
lempy Geschrieben 27. Dezember 2011 Autor Geschrieben 27. Dezember 2011 Hallo Klotzkopp Schöne Weihnachten gehabt? Habe die Tage über mein Problem nachgedacht und bin zu dem Ergebnis gekommen, dass ich das mit der verketten Liste noch nicht so ganz verstanden habe. Obwohl das auf den Zeichnungen recht einfach und verständlich dargestellt wurde. Doch wie setze ich diese Zeichnungen in Code um??? Versteh ich nicht. hilfsHandle wird ein Objekt "weiter" gesetzt. Somit zeigt hilfsHandle auf das neue, eben erstellte Objekt, damit man hinterher die Daten eintragen kann. listenende zeigt unverändert auf das "alte" letzte, jetzt vorletzte Listenelement. Eigentlich brauchst du listenende gar nicht, der Zeiger wird nicht benutzt. Hatte ich mir fast gedacht. Währe auch ein wenig zu Einfach. ch denke, genau das ist die Aufgabe. Dafür brauchst du in anhaengen allerdings keine neue Variable, du musst nur den Rückgabetyp ändern und den passenden Wert zurückgeben. Was ist der Rückgabetyp? Was ist der passende Wert? Ist der Wert listenanfang? Die Aufgabe lautet so: Das listenende soll nicht nach jedem neuen Anhängen erst neu ermittelt werden, sondern es soll in einen eigenen Handle gespeichert werden. Danach müsste ich einen zweiten Handle in der Funktion Anhaengen haben. Es sollte so aussehen das ich einen Speicher für listenangang und einen für listenende habe. Nur habe ich im Moment nicht den geringsten Schima, wie ich das umsetzen soll. Vielleicht kannst Dur mir noch mal eine Erklärung für Dumies zu Teil werden lassen. Gruß lempy 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.