![]() |
Problem mit Zeigern
Hallo,
ich habe in der Schule beim Umstieg von Pascal auf Delphi ein Problem. Und zwar bekomme ich beim Arbeiten mit Zeigern ständig einen Exeption Fehler angezeugt. Hier der problematische Programmteil:
Delphi-Quellcode:
wenn ich einen Wert eingebe, bleibt er jedesmal bei zhilf^.next:=NIL; stehen. nehm ich die zeile raus, weiter unten.
PROCEDURE push(VAR zkopf:tzeiger;inhalt:char;i:byte);
VAR zhilf,zneu:tzeiger; BEGIN zhilf:=zkopf; zhilf^.next:=NIL; IF NOT(i=1) THEN BEGIN REPEAT zhilf:=zhilf^.next; UNTIL zhilf^.next=NIL; END; new(zneu); zneu^.inhalt:=inhalt; zhilf^.next:=zneu; zneu^.next:=NIL; END; bei Pascal hatte ich das Problem nicht. Woran liegt das? Ich komm wirklich nicht mehr weiter Danke für eure Hilfe. mfg de präsi |
DP-Maintenance
Dieses Thema wurde von "Dax" von "Neuen Beitrag zur Code-Library hinzufügen" nach "Object-Pascal / Delphi-Language" verschoben.
|
Re: Problem mit Zeigern
wie rufst du die funktion auf und warum übergibst du zkopf als var parameter wenn du in der Funktion den Wert gar nicht neu setzt?
|
Re: Problem mit Zeigern
Zitat:
|
Re: Problem mit Zeigern
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Delphi-Quellcode:
"i" übernehme ich, weil die Funktion, die prüfen sollte, ob zkopf auf NIL zeigt auch diesen exeption fehler erzeugt hatte
init(zkopf);
laeng:=length(edit1.Text); FOR i:=1 TO laeng DO BEGIN push(zkopf,edit1.text[i],i); END; ja, das mit dem VAR parameter wurde uns glaub ich von meinem info lehrer so gesagt...scheint aber wirklich überflüssig zu sein danke PS: ich hab den Fehler nochmal als anhang hochgeladen |
Re: Problem mit Zeigern
Was soll den die Funktion genau machen?
|
Re: Problem mit Zeigern
anhand des Fehlers sag ich mal das "zkopf" nil ist. Und damit krachts natürlich beim zugriff auf next.
Anhand dessen was du bisher gepostet hast empfehle ich dir das Video Pointerfun ( ![]() |
Re: Problem mit Zeigern
Zitat:
dazu soll das eingabefeld ausgelesen werden und jedes zeichen einzeln in einen stack (die liste) geschrieben werden... danach wird gerechnet... |
Re: Problem mit Zeigern
Nochmal:
Delphi-Quellcode:
zhilf^.next:=NIL; //Nachfolger ist nil
IF NOT(i=1) THEN BEGIN REPEAT zhilf:=zhilf^.next; //jetzt ist auch zhilf nil UNTIL zhilf^.next=NIL; //next von nil^? |
Re: Problem mit Zeigern
Warum nicht einfach so?
Delphi-Quellcode:
PROCEDURE push(VAR zkopf:tzeiger;inhalt:char);
VAR zhilf,zneu:tzeiger; BEGIN zhilf:=zkopf; WHILE NOT (zhilf^.next=NIL) DO zhilf:=zhilf^.next; new(zneu); zneu^.inhalt:=inhalt; zhilf^.next:=zneu; zneu^.next:=NIL; END; |
Re: Problem mit Zeigern
Und zKopf ist dann die Wurzel?
Delphi-Quellcode:
PROCEDURE push(zkopf:tzeiger;inhalt:char;i:byte);
VAR zneu:tzeiger; BEGIN //Ermittle letztes Element while zhilf^.next<>NIL do zkopf := zkopf^.Next; new(zneu); zneu^.inhalt:=inhalt; zneu^.next:=NIL; zkopf^.next:=zneu; END; |
Re: Problem mit Zeigern
Zitat:
Delphi-Quellcode:
auch ein fehler
WHILE NOT (zhilf^.next=NIL) DO zhilf:=zhilf^.next;
|
Re: Problem mit Zeigern
garantiert der gleiche weil zu dem Zeitpunkt schon wieder versucht wird einen Zeiger zu derefernzieren der nil ist (hab ich oben bereits geschrieben).
|
Re: Problem mit Zeigern
Komisch... gib doch bitte mal die Definiton von TZeiger
|
Re: Problem mit Zeigern
Delphi-Quellcode:
WHILE (zhilf <> nil) and (zhilf^.next <> NIL) DO zhilf:=zhilf^.next;
|
Re: Problem mit Zeigern
er übergibt der Funktion Push bereits nil
|
Re: Problem mit Zeigern
Dann kann das nix werden, außer dass der Fehler dann später kommt.
|
Re: Problem mit Zeigern
Dein Code ist wirklich nicht sonderlich gut. In Pascal kann man sowas schreiben, aber Delphi hat ganz andere Konventionen.
Aber abgesehen von den Konventionen: Warum gehst du immer bis zum Ende hindurch? Wenn das ein Stack ist, könntest du auch einfach dein neues Element ganz vorne hinsetzen. Dann könntest du in konstanter Zeit pushen und poppen. Außerdem, warum machst du das nicht gleich in einer Klasse? |
Re: Problem mit Zeigern
Zitat:
Delphi-Quellcode:
hier die deklaration:
zhilf^.next:=zneu;
Delphi-Quellcode:
TYPE tzahl=char;
tinhalt=tzahl; tzeiger=^tknoten; tknoten= RECORD inhalt: tinhalt; next:tzeiger; END; VAR zliste,zkopf :tzeiger; |
Re: Problem mit Zeigern
Wenn Du nil an die Funktion übergibst, kommt der Fehler eben an der besagten Stelle.
|
Re: Problem mit Zeigern
Zitat:
hab das erst seit einer woche und wir hatten vorher nur mit pascal gearbeitet... könntet ihr also für einen totalen delphi anfänger den fehler noch einmal zusammenfassen? und wenn es nicht allzu viel umstände macht noch einen kleinen programmcode als verbesserung? wäre echt meine rettung, da mir das mit den zeigern in delphi nicht genauer erläutert wurde danke |
Re: Problem mit Zeigern
beim aufruf deiner Funktion "push" hat zkopf den Wert nil
das heißt er zeigt auf keinen Speicher. Dementsprechend kracht es immer sobald du auf Untereigenschaften davon zugreifen willst. Wie bereits erwähnt empfehle ich dir das Video Pointerfun damit du ein Gespür für Pointer bekommst. |
Re: Problem mit Zeigern
Ungetestet:
Delphi-Quellcode:
PROCEDURE push(VAR zkopf:tzeiger;inhalt:char);
VAR zhilf, zneu:tzeiger; BEGIN //erstes Element soll angelegt werden if zkopf = nil then begin new(zhilf); zhilf^.inhalt := inhalt; zhilf^.next := nil; end //eine weiteres Element soll angehängt werden else begin zhilf:=zkopf; while (zhilf <> nil) and (zhilf^.next <> nil) do zhilf:=zhilf^.next; new(zneu); zneu^.inhalt:=inhalt; zneu^.next:=NIL; zhilf^.next:=zneu; end; zkopf := zhilf; END; |
Re: Problem mit Zeigern
Zitat:
werd mir das mal genauer anschauen, damit ich verstehe, warum bei mir immer der Fehler erzeugt wurde... danke nochmal für eue hilfe |
Re: Problem mit Zeigern
Stimmt, daran dass zkopf schon mit nil übergeben wird, habe ich gar nicht gedacht ;-)
@DeddyH: Hier
Delphi-Quellcode:
ist die erste Abfrage (zhilf<>nil) unnötig ;-)
while (zhilf <> nil) and (zhilf^.next <> nil) do
zhilf:=zhilf^.next; zhilf kann ja nie nil werden. |
Re: Problem mit Zeigern
Stimmt, war noch vom C&P übrig geblieben (schadet aber auch nicht) :zwinker:
|
Re: Problem mit Zeigern
aber müsste nicht das:
Delphi-Quellcode:
ganz vor, als letzte zeile der ersten fallunterscheidung?
zkopf := zhilf;
sonst könnte ich ja nie mehr auf das erste element zugreifen!? |
Re: Problem mit Zeigern
Durch diese Zuweisung hast Du immer das letzte Element der Liste in zkopf stehen. Soll das nicht so sein?
|
Re: Problem mit Zeigern
Zitat:
|
Re: Problem mit Zeigern
Nö, ist kein Aufwand, dann mach es so, wie Du selbst schon gesagt hast:
Delphi-Quellcode:
PROCEDURE push(VAR zkopf:tzeiger;inhalt:char);
VAR zhilf, zneu:tzeiger; BEGIN //erstes Element soll angelegt werden if zkopf = nil then begin new(zhilf); zhilf^.inhalt := inhalt; zhilf^.next := nil; zkopf := zhilf; end //eine weiteres Element soll angehängt werden else begin zhilf:=zkopf; while (zhilf <> nil) and (zhilf^.next <> nil) do zhilf:=zhilf^.next; new(zneu); zneu^.inhalt:=inhalt; zneu^.next:=NIL; zhilf^.next:=zneu; end; END; |
Re: Problem mit Zeigern
Zitat:
|
Re: Problem mit Zeigern
[OT] Gibt es hier eigentlich noch kein Tut zu einfach/doppelt verketteten Listen? Wäre ja mal 'ne schöne Gelegenheit, sich mit seinem neuen Delphi vertraut zu machen :mrgreen: [/OT]
|
Re: Problem mit Zeigern
tja, mal 'n hinweis, hier wird das thema auch behandelt:
![]() ausserdem gibts massenweise threads und tutorials über verkettete listen z.b. ![]() ![]() ![]() |
Re: Problem mit Zeigern
Also, Tuts hab ich auf Anhieb keine entdeckt, und bei den meisten (aktuellen) gefundenen Threads innerhalb der DP war ich selbst beteiligt ;)
|
Re: Problem mit Zeigern
ich hab noch ein kleines problem...
und zwar, wenn ich nun eine zweite liste erzeuge und dort soll die erste in umgekehrter reihenfolge hineingeschrieben werden..... dafür habe ich zkopf und zkopf2 in der ersten unit deklariert...die waren vorher gar nicht deklariert allerdings bekomme ich jetzt immer diese fehlermeldung: [Fehler] Unit1.pas(51): Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen hier nocheinmal die zugehörige Prozedur:
Delphi-Quellcode:
die pop-funktion:
procedure TForm1.Button1Click(Sender: TObject);
VAR laeng,i:byte; zkopf,zkopf2 :tzeiger; begin init(zkopf); laeng:=length(edit1.Text); FOR i:=1 TO laeng DO push(zkopf,edit1.text[i]); init(zkopf2); FOR i:=1 TO laeng DO push(zkopf2,pop(zkopf)); edit1.text:=top(zkopf2); end;
Delphi-Quellcode:
FUNCTION pop(VAR zkopf:tzeiger):char;
VAR zhilf1,zhilf2:tzeiger; z:char; BEGIN zhilf1:=zkopf; zhilf2:=zkopf^.next; WHILE NOT(zhilf2^.next = NIL) DO BEGIN zhilf1:=zhilf2; zhilf2:=zhilf2^.next; END; zhilf1^.next:=NIL; pop:=zhilf2^.inhalt; END; und die im vorigen teil besprochene push prozedur:
Delphi-Quellcode:
danke
PROCEDURE push(VAR zkopf:tzeiger;inhalt:char);
VAR zhilf, zneu:tzeiger; BEGIN //erstes Element soll angelegt werden if zkopf = nil then begin new(zhilf); zhilf^.inhalt := inhalt; zhilf^.next := nil; zkopf := zhilf; end //eine weiteres Element soll angehängt werden else begin zhilf:=zkopf; while (zhilf <> nil) and (zhilf^.next <> nil) do zhilf:=zhilf^.next; new(zneu); zneu^.inhalt:=inhalt; zneu^.next:=NIL; zhilf^.next:=zneu; end; END; |
Re: Problem mit Zeigern
Würde statt
Delphi-Quellcode:
FUNCTION pop(VAR zkopf:tzeiger):char;
VAR zhilf1,zhilf2:tzeiger; z:char; BEGIN zhilf1:=zkopf; zhilf2:=zkopf^.next; WHILE NOT(zhilf2^.next = NIL) DO BEGIN zhilf1:=zhilf2; zhilf2:=zhilf2^.next; END; zhilf1^.next:=NIL; pop:=zhilf2^.inhalt; END; nicht einfach nur
Delphi-Quellcode:
genügen?
FUNCTION pop(VAR zkopf:tzeiger):char;
BEGIN result:=zkopf^.inhalt; zkopf := zkopf^.next END; |
Re: Problem mit Zeigern
Achso, nein würde es nicht, weil du ja keine FIFO-Schlage sondern einen LIFO-Keller willst. Sorry ;-)
Allerdings würde mein Vorschlag passen, wenn du für das Push auch eine entsprechende Prozedur verwenden würdest, die das neue Element am Anfang einfügt, die übrigens viel einfacher wäre. |
Re: Problem mit Zeigern
Zitat:
denn, wenn zkopf das erste element ist und pop jeweils das letzte entfernen und freigeben soll muss ich ja solange in der liste weitergehen, bis ein element auf nil zeigt, oder? bei mir hängts im moment an der letzten zeile der pop prozedur
Delphi-Quellcode:
es kommt wieder jedesmal ein exeption fehler
FUNCTION pop(VAR zkopf:tzeiger):char;
VAR zhilf1,zhilf2:tzeiger; BEGIN zhilf1:=zkopf; zhilf2:=zkopf^.next; WHILE (zhilf2 <> nil) AND (zhilf2^.next <> NIL) DO BEGIN zhilf1:=zhilf2; zhilf2:=zhilf2^.next; END; zhilf1^.next:=NIL; pop:=zhilf2^.inhalt; END; |
Re: Problem mit Zeigern
Schau mal, so klappts:
Delphi-Quellcode:
PROCEDURE push(VAR zkopf:tzeiger;inhalt:Char);
var zhilf:tzeiger; BEGIN new(zhilf); zhilf^.inhalt:=inhalt; zhilf^.next:=zkopf; zkopf:=zhilf END; FUNCTION pop(VAR zkopf:tzeiger):char; BEGIN result:=zkopf^.inhalt; zkopf := zkopf^.next END; Hab ich erfolgreich gesetet mit:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var tmp:tzeiger; begin push(tmp,'a'); push(tmp,'b'); push(tmp,'c'); showmessage(pop(tmp)); //c showmessage(pop(tmp)); //b showmessage(pop(tmp)); //a end; |
Re: Problem mit Zeigern
Zitat:
probiers gleich mal mit deiner vorgeschlagenen prozedur |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 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