Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Prism Liste mit Zeigern (https://www.delphipraxis.net/112450-liste-mit-zeigern.html)

Damaster 21. Apr 2008 16:31


Liste mit Zeigern
 
Hallo Leute!

Wir haben in der Schule mit Listen angefangen. Soweit ja ganz toll, nur verstehe ich nicht so ganz was ich da immer falsch mache.
Unser Lehrer gibt aber auch keine klaren Auskünfte. Es gibt öfter Probleme, die nicht sein müssten. Falsche Funktionen etc...

Nun zu meinem Problem. Wie kann ich dem Pc klarmachen, dass er Alle Elemente der Liste durchgeht bis zum letzten, dass dann auf Nil zeigt?
Ist die Deklaration mit dem Anker überhaupt richtig?

Delphi-Quellcode:
type Pzeiger= ^Tmensch;
     Tmensch = record
                n:string;
                z:pzeiger;
                end;

var anker:pzeiger;

procedure TForm1.FormCreate(Sender: TObject);
begin
 new(anker);
 anker.z:=nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
 var pak,pvor,pan:pzeiger;
begin
   if anker.z=nil then
                     begin
                         new(pak);
                         anker^.z:=addr(pak);
                         pak^.n:=edit1.text;
                         pak^.z:=nil;
                      end
                   else begin
                     pak:=anker^.z;
                     while pak<>nil do begin
                     pak:=pak^.z;
                     end;
                    end;
end;
Anmerkung:
n im Record steht für einen Namen.
Ich weis moment is der Quelltext noxh recht unübersichtlich, aber vll kann mir ja jemand sagen wo der Fehler liegt. Das Programm soll einfach namen in eine Liste schreiben. Imer ans Ende, wenn der aktuelle Datensatz nicht das letzte Element is soll er von Anfang an die Liste durchgehn bis zum letzten also bis der Zeiger auf Nil zeigt.

mkinzler 21. Apr 2008 16:36

Re: Liste mit Zeigern
 
Warum erzeugst du nur ein ein neues Element, wenn die Liste leer ist?

BTW. Stimmt das mit Delphi.Net? Dann sollte man auf Zeiger verzichten
Es geht nichts über aussagekräftige Komponentenbezeichnungen (Button1)

DeddyH 21. Apr 2008 16:44

Re: Liste mit Zeigern
 
Zu Zeigern und Listen gibt es hier neuerdings ein Tutorial :mrgreen:

Damaster 21. Apr 2008 19:01

Re: Liste mit Zeigern
 
Das Tutorial hat mir leider nicht viel geholfen.
Die eine Fehlermeldung ist zwar weg, aber dafür kommt die nächste.
Wie gesagt wir bekommen ja keine Informationen von unserem Lehrer. ICh weis nur ich brauch einen Anfang, den er Anker annte, der kann ja am Anfang wenn noch nichts da ist auf nichts zeigen. Danach gebe ich das erste element ein
Delphi-Quellcode:
type Pzeiger= ^Tmensch;
     Tmensch = record
                n:string;
                z:pzeiger;
                end;

var anker:pzeiger;

procedure TForm1.FormCreate(Sender: TObject);
begin
new(anker);
anker.z:=nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
var pak,pvor,pan:pzeiger;
begin
   if anker.z=nil then
                     begin
                         new(pak);
                         anker^.z:=addr(pak);
                         pak^.n:=edit1.text;
                         pak^.z:=nil;
                      end
Dieses Wird wenn man es mit showmessage abfragt auch noch richtig wiedergegeben.
Jetzt fängt mein Problem an. Jetzt will ich ein weiteres Element anknüpfen. Ich gehe also zum sog. Anker und sehe nach worauf er zeigt. Also auf pak. Von dort aus sollen wir weiter überprüfen ob dieser auf ein weiteres glied zeigt oder ob es das letzte ist.
Delphi-Quellcode:
else
begin
      pak:=anker^.z;
      while pak<>nil do
                       begin
                          new(pak);
                          pak:=pak^.z;
                          pan:=pak;
                        end;
      new(pak);
      pak^.s:=Edit1.text;
      new(pan);
      pan^.z:=addr(pak);
      pak^.z:=nil;
end;
end;
Wodraus ich auch nicht ganz schlau wurde, ist wann ich dieses ^ brauche und wann nicht. muss ich pan^.s:='string' schreiben oder geht auch pan.s:='string'??

mkinzler 21. Apr 2008 19:04

Re: Liste mit Zeigern
 
^ Vor der Variable heisst Zeiger auf Objekt, dahinter Objekt aus Zeiger

Damaster 21. Apr 2008 19:12

Re: Liste mit Zeigern
 
das heisst vor der Variabeln brauch ich es nur bei der Deklaration der Variabeln.
Hinter der Variabeln wenn ich aus einem Zeiger das Objekt erhalten möchte.
und wenn ich es nicht schreibe, dann erwartet der pc einen Zeiger? also eine Anweisung, wohin er zeigen soll?

mkinzler 21. Apr 2008 19:15

Re: Liste mit Zeigern
 
Zitat:

das heisst vor der Variabeln brauch ich es nur bei der Deklaration der Variabeln.
Und um eine Zeiger auf ein Objekt zu erhalten.
Zitat:

Hinter der Variabeln wenn ich aus einem Zeiger das Objekt erhalten möchte.
Ja
Zitat:

und wenn ich es nicht schreibe, dann erwartet der pc einen Zeiger? also eine Anweisung, wohin er zeigen soll?
Ja

Klaus01 21. Apr 2008 19:23

Re: Liste mit Zeigern
 
Delphi-Quellcode:
type Pzeiger= ^Tmensch;
     Tmensch = record
                n:string;
                z:pzeiger;  // hier sollte die Adresse des nächsten Elementes stehen
     end;

var anker:pzeiger;

procedure TForm1.Button1Click(Sender: TObject);
var pak,pvor,pan:pzeiger;
begin
  if anker.z=nil then // hier fragst Du ob das AnkerElement einen Zeiger auf das nächste Element hat
    begin
      new(pak);
      anker^.z:=addr(pak);
      pak^.n:=edit1.text;
      pak^.z:=nil;
    end

meiner Meinung nach wäre es so besser:

Delphi-Quellcode:
type Pzeiger= ^Tmensch;
     Tmensch = record
                n:string;
                naechster:pzeiger;
     end;

var anker:pzeiger;

procedure TForm1.Button1Click(Sender: TObject);
var pak,pvor,pan:pzeiger;
begin
  if anker = nil then // gibt es schon ein erstes Element?
    begin
      new(pak);
      anker := pak ;     //das erste Element hat die Adresse von pak
      pak^.n:=edit1.text;
      pak^.naechster:=nil;       // es gibt noch kein neues Element dager pak^.naechster := nil
    end
Zum Anhänge suchst Du dir das Element dessen Nachfolger nil ist:

Delphi-Quellcode:
procedure TForm1.addElement(s:String);
var
  list : pzeiger;
  dummy : pzeiger;
begin
  list := anker;
  while list^.naechster <> nil do
    list := list^.naechster;
  // hier hat list^.naechster die Adress nil
  // damit hat list die Adresse des letzten Elementes
  new(dummy);
  dummy^.n:=string;
  dummy ^.naechster:=nil;
  list^.naechster := dummy;
end;
Grüße
Klaus

Damaster 21. Apr 2008 19:45

Re: Liste mit Zeigern
 
Vielen Dank Klaus!
Und natürlich auch an die Anderen. Jetzt versteh ich schon besser wie das mit dem Zeiger funktionieren soll. :thumb:
Ich denke der rest wird sich ergeben, wenn wir weiter an programmen üben.
nur noch eine Frage Klaus, wenn ich schreibe anker:=pak, was genau enthällt dan anker? anker ist ja ein zeiger, der auf ein record aus string und pointer zeigt. so jedenfalls haben wir es in der schule erklärt bekommen. Anker wäre doch dann ein Element der liste, genau wie pak, jedoch mit einem "besonderen namen", mit dem man anfängt. Oder sehe ich das falsch? :?:

mkinzler 21. Apr 2008 19:50

Re: Liste mit Zeigern
 
Anker ist ein Zeiger, der auf das erste Element der Liste zeigt.

Damaster 21. Apr 2008 20:16

Re: Liste mit Zeigern
 
ok
wieso heist es dan in dem fall nicht anker.naechster? anker ist vom typ pzeiger.
normal ist es doch der teil hinter dem punkt also ".naechster" der irgendwohin zeigt.
anker:=pak da wird ja noch der Stringteil mitübergeben, oder etwa nicht?
weiter unten hat Klaus ja list^.naechster:=dummy geschrieben. Wieso geht dann hier nicht anker^.naechster:=pak?

mkinzler 21. Apr 2008 20:21

Re: Liste mit Zeigern
 
Weil das ein Zeiger auf den Nachfolger des Elements (also das 2. Element ist)
Zitat:

anker:=pak da wird ja noch der Stringteil mitübergeben, oder etwa nicht?
Nein der Zeiger Anker wird auf die Adresse gesetzt, welche auch pak referenziert.
Zitat:

weiter unten hat Klaus ja list^.naechster:=dummy geschrieben. Wieso geht dann hier nicht anker^.naechster:=pak?
Weil Amker Nil ist.

Damaster 21. Apr 2008 20:42

Re: Liste mit Zeigern
 
also ist anker einfach ein zeiger auf das erste element der liste. sprich den ersten datensatz an dea der zeiger auf das nächste element verknüpft ist.
Dann habe ich da wohl was falsch verstanden. jetzt ist mir auch klar warum ich immer solche dubiosen Fehlermeldungen hatte. Ich dachte immer ich muss anker^.z was zuordnen, wie jedem späteren Listenelement. Da programmiert man 2 Doppelstunden und fragt sich warum das nicht geht.
Naja danke an alle. Ich denke mit dem wissen sollte es mit ein wenig übung schon funktionieren. :thumb: :hi:

Klaus01 21. Apr 2008 20:46

Re: Liste mit Zeigern
 
Zitat:

Zitat von Damaster
..weiter unten hat Klaus ja list^.naechster:=dummy geschrieben. Wieso geht dann hier nicht anker^.naechster:=pak?

Ich habe da eine gesonderte Variable genommen, weil das Ankerelement nicht mehr verändert werden sollte
wenn es bereits Listenelemente gibt.
Der Anker wird beim ersten Element festgelegt.
Und wenn das letzte Element aus der Liste gelöscht wurde, wird
Anker wieder auf nil gesetzt.

Wenn ich die while Schleife mit Anker gemacht hätte,
wäre die Adresse von Anker verändert worden und der Listenanfang
wäre den Bach hinunter gegangen - die Folge davon sind dann
sogenannte Speicherlecks.

Grüße
Klaus

grenzgaenger 21. Apr 2008 23:32

Re: Liste mit Zeigern
 
Nr. 1: solltest du deine proceduren/methoden mal benennen, damit man weiss was sich bspw. hinter button1 verbirgt.

Nr. 2: anlegen von knoten geht wie folgt:
NewNode := Node.create;
if anker = NULL then Anker.next := NewNode
else
begin
While anker.next <> NIL then ANKER := ANKER.next;
ANKER.next := newNode;
end;


Nr. 3: Löschen geht wie folgt:
temp:= Anker;
While ANKER.Next <> NIL do
begin
Temp := Anker;
ANKER := AnKER.next;
free(temp);
Temp := Anker;
end;
if temp <> NIL then free(anker)

Nr. 3: Traversieren;
Tmp := Anker.next;
While tmp <> NIL and not tmp.content <> content do
tmp := tmp.next;

ansonsten, machst du es deinem PC klar, was du von ihm willst, indem du es ihm kleinigkeit für kleinigkeit erklärst :-)

<HTH>

grenzgaenger 21. Apr 2008 23:34

Re: Liste mit Zeigern
 
[quote="Klaus01"]Ich habe da eine gesonderte Variable genommen, weil das Ankerelement nicht mehr verändert werden sollte/quote]

Anmerkung: der anker darf nicht mehr verändert werden, ausser die liste ist aufgelöst. ansonsten ist der anker untouchable.

<HTH>


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:18 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