![]() |
Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Hi Leute, ich hoffe ich bin hier im richtigen Forum.
Hoffe doch dass Zeiger zum ObjectPascal gehören. :gruebel: Also mein Problem konnte Google nicht lösen. Fast jeder Google-Link ist schon mit lilaner Farbe gekennzeichnet ;) Dazu kommt noch,dass mein Desktop jetzt mit haufen Beispielen und PDFs zugemüllt ist. Nur nix davon bringt mich wirklich weiter. Aber nun genug Offtopic. Mein Problem ist folgendes: Ich hab mir einen Zeiger definiert:
Code:
Dann kommen die globalen Variablen
type
PMyelement = ^TMyelement; TMyelement = record id: integer; titel: string; Next : PMyelement; Prev : PMyelement;
Code:
var
anf, akt, ende : PMyelement; { ** anf und akt stehen für Anfang und Aktuell ** } Bis dahin kein Problem. Jetzt (ich hoffe ich kriegs gut erklärt) möchte ich meinen Quelltext folgdendermaßen schreiben: Das Einschreiben von Daten funktioniert schon. Allerdings fügt er neue Elemente immer ganz hinten an. Sagen wir aber ich befinde mich in der Mitte der Datensätze (die ich mit Hilfe von Vorwärts/Rückwärts-Buttons erreicht habe) und klicke nun auf "Übernehmen". Dann soll er in dem aktuellen Datensatz nur die Daten "aktualisieren" und nicht hinten erneut speichern. Anschließend soll er mir den nächsten Datensatz einfach anzeigen lassen. Ich weiß ja auch warum er die Daten am Ende speichert, aber ich krieg diesen Fehler gedanklich nicht ausgemerzt! Es fehlt mir irgendwo ne If-Abfrage die überprüft, ob der Zeiger nun am Ende des Datensatzes ist (sprich "nächste Datensatz := NIL") oder ob da noch Datensätze folgen (sprich "nächste Datensatz <> NIL") Ich hoffe einfach mal,dass die Beschreibung ausreicht für euch. Wenn es fragen gibt immer her damit! Hier mein Quelltext zum Eintragen von Daten:
Code:
procedure TForm1.BitBtn3Click(Sender: TObject); // Elemente einschreiben in Liste
var h1, h2 : PMyelement; { ** h1 und h2 sind (H)ilfsvariablen ** } begin new(h1); h1^.id := StrToInt(Edit1.Text) +1; h1^.titel := Edit2.Text; Edit1.Text := IntToStr(h1^.id); h1^.Next := NIL; if anf = NIL then begin anf := h1; end else begin h2 := anf; while (h2^.Next <> NIL) do begin h2 := h2^.Next; end; h2^.Next := h1; end; akt := h1; end; lg knocko |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Hallo,
wenn Du "nur" die Daten eines Feldes ändern willst und aktuell der Zeiger auf das aktuelle Feld ist:
Delphi-Quellcode:
Die Zeiger auf das vorhergehende Element und das nachfolgende Element
aktuell^.id:=IntToStr(edit1.Text);
aktuell^.titel :=Edit2.Text; werden nicht geändert. Anders sieht es aus, wenn Du ein Element in die Liste einfügen willst. Aber laut Deiner Beschreibung willst Du das ja nicht. Grüße Klaus [edit] Rechtschreibung |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Wenn du nur einen vorhandenen Datensatz editieren willst, darfst du mit new() keinen Neuen erzeugen, sondern musst den Inhalt des aktuellen Datensatzes ändern....
Oder verstehe ich dich falsch? // edit: Nein, offenbar richtig verstanden! Also: Nicht new() verwenden!! |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Liste der Anhänge anzeigen (Anzahl: 1)
Hm naja ich habs ja schon mal anders versucht, aber mit meiner geistigen Kompetenz ist da eher Bullsh*t rausgekommen, anstatt ein vernünftiger Quelltext ;)
Ich muss sagen, dass der jetzige Quelltext, den ich zusammengewürfelt habe eigentlich eher aus dem Internet rauskopiert ist. Dadurch ist er noch nicht wirklich auf meine Bedürfnisse zusammengeschnitten. Ich hab mich aber bemüht, den Quelltext Zeile für Zeile zu verstehen und bin soweit, dass ich weiß was bei jeder Zeile gemacht wird. Und da komm ich zum Entschluss, dass die While Schleife evtl. durch eine If-Abfrage ersetzt werden kann. Nur da bekomm ich meine Probleme. Die If Abfrage hab ich mir so vorgestellt:
Code:
Button Klick
begin speichere daten in zeiger if (wenn...) nächstes glied = leer/nicht vorhanden/nil dann mach Edit1.text := IntToStr(zeiger.id) + 1; // Dieser Teil soll einfach nur die Felder "vorbereiten" sodass ich neue eingaben machen kann. Edit2.Text := '' else Zeige mir Daten vom nächsten Listenglied in Edit1 und Edit2 // Soll einfach das nächste Glied anzeigen end So ungefähr soll es laufen, wenn ich auf den Button klicke. @taaktaak Das new() muss ich einbauen. ANsonsten kommt ein fehler. Und wenn ich new() beim Form.Create einbaue, dann funktioniert meine Vorwärts/Rückwärts-Blätter funktio nicht mehr. |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Zu verketteten Listen gibt es hier in der DP ein
![]() |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Vorausgesetzt der Pointer "aktuell" zeigt auf das aktuelle Listenelement:
Delphi-Quellcode:
Grüße
//Button Klick
begin //speichern aktuell^.id:=StrToint(Edit1.Text); aktuell^.titel:=Edit2.Text; //if (wenn...) nächstes glied nicht leer/vorhanden/<> nil dann if aktuell^.next <> nil then begin aktuell:=aktuell^.next; //mach Edit1.text := IntToStr(zeiger.id) + 1; // Dieser Teil soll einfach nur die //Felder "vorbereiten" sodass ich neue eingaben machen kann. Edit1.text:=IntToStr(aktuell^.id); Edit2.Text:=aktuell^.titel; end else // Listenende begin Edit2.Text := '' Edit1.text:=IntToStr(aktuell^.id +1); end; end; Klaus |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Ja, genau so hatte ich es schonmal gehabt. ;)
Und da kommt mein Programm nicht klar. Sieht so aus, als würde er nur das erste Glied einschreiben. Würde es euch helfen, wenn ich das Programm online stelle? Würde sich jemand damit beschäftigen? |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
So, jetzt mal Butter bei die Fische.
Der Übernehmen Button, was soll er machen? a) Ein neues Element in die Liste einfügen? b) Die Daten in ein bestehendes Listenelement schreiben? Wie fügst Du neue Elemente in die Liste ein? Aktuallisiertst Du immer den Pointer aktuell wenn Du dich in der Liste bewegst? Grüße Klaus |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Der Button soll:
a) Entweder neues Element in die Liste einfügen und dann die Felder quasi "vorbereiten", sodass ein neues nächstes Element eingetragen werden kann b) oder (wenn schon eins vorhanden ist) soll er das vorhandene blos überschreiben bzw. aktualisieren und automatisch zum nächsten Listenglied wandern und anzeigen Der Fall b) würde ja eintreffen, wenn ich Rückwärts in der Liste gehe. Das ist mein "Übernehmen" Button. Von mir aus kannst du auch andre Variablennamen nutzen. Die Namen sind nur ausm Internet rauskopiert :( Dazu hab ich noch deinen Quelltext genommen
Code:
procedure TForm1.BitBtn3Click(Sender: TObject); // Elemente einschreiben in Liste
begin new(h1); h1^.id := StrToInt(Edit1.Text) +1; h1^.titel := Edit2.Text; Edit1.Text := IntToStr(h1^.id); h1^.Next := NIL; if anf = NIL then begin anf := h1; end else if akt^.Next <> nil then begin Edit1.Text := IntToStr(akt^.id); Edit2.Text := akt^.titel; end else begin Edit2.Text := ''; Edit1.Text := IntToStr(akt^.id+1); end; akt := h1; end; Das ist mein Vorwärts-Button
Code:
procedure TForm1.BitBtn4Click(Sender: TObject); // Vorwärts blättern
begin if akt^.Next <> NIL then { ** Wenn akt^.Next Inhalt aufweist, dann... ** } begin akt := akt^.Next; { ** ...geh bei jedem Klick auf den Vorwärts-Button ein Listenglied weiter. ** } Edit1.Text := IntToStr(akt^.id); { ** Trägt die aktuellen ("akt") Werte, bei dem der Zeiger steht, in die Edit-Komponenten ** } Edit2.Text := akt^.titel; end else begin Edit1.Text := IntToStr(akt^.id+1); { ** Wenn das Ende erreicht ist, werden die Felder so vorbereitet, dass man gleich ein neues Element eintragen kann ** } Edit2.Text := ''; end; end; Der Button sorgt dafür, dass ich wieder am Anfang der Liste lande
Code:
procedure TForm1.BitBtn1Click(Sender: TObject); // Erste Glied anzeigen lassen
begin akt := anf; { ** Zeiger wird auf das erste Record gesetzt ** } Edit1.Text := IntToStr(akt^.id); { ** Trägt die Werte vom ersten Listenglied in die Editkomponenten ein ** } edit2.Text := akt^.titel; end; Achso und PS: Das Tutorial hab ich schon runtergeladen. Ist eines von vielen auf meinem Desktop ;) Wie gesagt -> Fast alle Google Links sind Lila :) |
Re: Problem mit doppelt Verkettete Liste - Zeiger - Wie? ^^
Zitat:
Delphi-Quellcode:
Wenn Du ein Feld überschreiben willst, solltest Du nur den Inhalt überschreiben,
procedure TForm1.BitBtn3Click(Sender: TObject); // Elemente einschreiben in Liste
begin new(h1); h1^.id := StrToInt(Edit1.Text) +1; h1^.titel := Edit2.Text; Edit1.Text := IntToStr(h1^.id); h1^.Next := NIL; if anf = NIL then begin anf := h1; end else if akt^.Next <> nil then begin Edit1.Text := IntToStr(akt^.id); Edit2.Text := akt^.titel; end else begin Edit2.Text := ''; Edit1.Text := IntToStr(akt^.id+1); end; akt := h1; // hier machst Du dir die Liste kaputt end; nicht auch noch die Adresse des Feldes. Wenn Du ein Feld hinzufügen willst, musst Du mit new() ein Feld erstellen und dieses an die Liste anhängen. Der Einfachheit halber würde ich das mit zwei Buttons machen wollen einen mit Namen "hinzufügen" und einen mit Namen "überschreiben". Auch solltest Du noch darauf achten bei Deinem Pointer das Element prev zu versorgen, denn sonst gibt es Probleme in der Liste nach vorne zu wandern. .. und noch ein Link zu ![]() Musst Du mit Pointerlisten arbeiten, wenn nicht, kannst Du dir mal dynamische Array oder auch die Klasse TList anschauen. Grüße Klaus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz