Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Listen und wie man sie nutzt (https://www.delphipraxis.net/152461-listen-und-wie-man-sie-nutzt.html)

idefix2 23. Jun 2010 21:21

AW: Listen und wie man sie nutzt
 
So wie Du es programmiert hast, müsste der Index von 0 bis count-1 und nicht von 1 bis count laufen.
In Deiner getdeveloperbyindex Funktion fehlt jede Art von fehlerbehandlung, wenn der Index zu gross ist (wie es eben hier der Fall ist), deshalb läuft das ganze in eine Exception.

Eine Schleife, bei der zu Beginn die Durchlaufzahl feststeht, wie in developerbyindex, sollte übrigens immer als for und nicht als while-Schleife realisiert werden, das trägt zum leichteren Verständnis bei.

Wenn in der Schleife beim Weiterschalten einmal nil kommt, dann war der Inder zu gross, da gehört eine Fehlermeldung oder was auch immer hinein.

Obelisk2k5 23. Jun 2010 21:49

AW: Listen und wie man sie nutzt
 
Die whileschleife hatte ich nur zu testzwecken drin.
Habe die Prozedur nun umgeschrieben und auch eine Bereichsprüfung eingebaut.

Delphi-Quellcode:
function getDeveloperByIndex(index: Cardinal): TDeveloper;
var
  temp : TDeveloper;
  i: Integer;
begin
  current := first;
  if index <= DevelopersCount then
    for i := 0 to index do
      current := current^.Next;
  getDeveloperByIndex := current^.content;
end;
Nur ist der Fehler ja ein lesefehler, d.h. der Fehler muss ein anderer sein...

idefix2 23. Jun 2010 22:01

AW: Listen und wie man sie nutzt
 
Noch einmal: Der Index läuft von 0 bis count-1 !

Du prüfst jetzt, ob index <= Count ist. Wenn Index = Count ist, dann ist Index um 1 zu gross.

Zitat:

In einer anderen Unit lasse ich eine for-Schleife von 1 - developersCount durchlaufen,

Obelisk2k5 23. Jun 2010 22:23

AW: Listen und wie man sie nutzt
 
Zitat:

Zitat von idefix2 (Beitrag 1031171)
Noch einmal: Der Index läuft von 0 bis count-1 !

Du prüfst jetzt, ob index <= Count ist. Wenn Index = Count ist, dann ist Index um 1 zu gross.

Zitat:

In einer anderen Unit lasse ich eine for-Schleife von 1 - developersCount durchlaufen,

Dann halt so.
Delphi-Quellcode:
function getDeveloperByIndex(index: Cardinal): TDeveloper;
var
  temp : TDeveloper;
  i: Integer;
begin
  current := first;
  if index <= DevelopersCount then
    for i := 0 to index-1 do
      current := current^.Next;
  getDeveloperByIndex := current^.content;
end;
Die Funktion liefert jetzt doch garantiert den developer an [index]. Stelle in der Liste.

Jetzt habe ich noch

Delphi-Quellcode:
procedure TFrmManageDevelopers.refreshDevelopers;
var
  I : byte;
begin
LstBxDevelopers.Clear;
for I := 1 to developersCount do
  LstBxDevelopers.Items.Append(developerToStr(getDeveloperByIndex(I)));
end;
Ich sehe da kein Problem.

Und die Fehlermeldung rührt ja immernoch von einem Lesefehler her.
Ich würde nur gern wissen, wieso.

generic 23. Jun 2010 23:00

AW: Listen und wie man sie nutzt
 
Records haben im Zeitalter der OO ausgedient.

Ich würde Objekte/Klassen erstellen welche die Daten halten sollen. Mit generics würde ich dann eine TObjectList ableiten, welche die Datenobjekte aufnimmt.
Wenn wie OL nun auch noch die Objekte besitzt, dann braucht man sich nicht einmal um das freigeben kümmern.
ForEach wird ebenfalls unterstützt.

Weitere Überlegung: Warum soviel Code schreiben, welche Fehler enthalten kann, wenn schon alles fertig ist.

Obelisk2k5 23. Jun 2010 23:07

AW: Listen und wie man sie nutzt
 
Zitat:

Zitat von generic (Beitrag 1031181)
Records haben im Zeitalter der OO ausgedient.

Ich würde Objekte/Klassen erstellen welche die Daten halten sollen. Mit generics würde ich dann eine TObjectList ableiten, welche die Datenobjekte aufnimmt.
Wenn wie OL nun auch noch die Objekte besitzt, dann braucht man sich nicht einmal um das freigeben kümmern.
ForEach wird ebenfalls unterstützt.

Weitere Überlegung: Warum soviel Code schreiben, welche Fehler enthalten kann, wenn schon alles fertig ist.

Die Records sind vorgegeben.

Und wo steht, das alles fertig sei?

idefix2 24. Jun 2010 00:03

AW: Listen und wie man sie nutzt
 
Überleg einmal, was passiert, wenn es genau ein Listenelement gibt.

Dein Developerbyindex wird genau einmal mit dem Parameter index=1 aufgerufen.

Delphi-Quellcode:
if index <= DevelopersCount
liefert true

Delphi-Quellcode:
for i := 0 to index-1 do
-> from 0 to 0, schleife wird genau einmal durchlaufen

Delphi-Quellcode:
current := current^.Next;
-> first^.next = nil, weil es ja nur ein Listenelement gibt, der next pointer des ersten Listenelemts zeigt also auf kein weiteres.

current^.content = nil^.content = exception.


Im Posting 11 habe ich Dir schon geschrieben:

Zitat:

Wenn in der Schleife beim Weiterschalten einmal nil kommt, dann war der Index zu gross, da gehört eine Fehlermeldung oder was auch immer hinein.
Wenn Du das so überprüft hättest, hättest Du den Fehler schon längst gefunden.


Wenn Du das ERSTE Listenelemnt haben willst, musst Du 0 mal in der Schleife weitergehen, weil dzu Beginn zeigt Dein current ja schon auf das erste Element.
Du durchläufst die Schleife prinzipiell einmal zu oft, und fliegst deswegen am Ende hinaus.#

Obelisk2k5 24. Jun 2010 00:10

AW: Listen und wie man sie nutzt
 
Zitat:

Zitat von idefix2 (Beitrag 1031188)
Überleg einmal, was passiert, wenn es genau ein Listenelement gibt.

Dein Developerbyindex wird genau einmal mit dem Parameter index=1 aufgerufen.

if index <= DevelopersCount liefert true

for i := 0 to index-1 do -> from 0 to 0, schleife wird genau einmal durchlaufen

current := current^.Next; -> first^.next = nil, weil es ja nur ein Listenelement gibt.

current^.content = nil^.content = exception.

Oh, das habe ich ja gar nicht gesehen.

Delphi-Quellcode:
function getDeveloperByIndex(index: Cardinal): TDeveloper;
var
  temp : TDeveloper;
  i: Integer;
begin
  current := first;
  if (index <= DevelopersCount) and (DevelopersCount > 1) then
    for i := 1 to index-1 do
      current := current^.Next;
  getDeveloperByIndex := current^.content;
end;
Sollte dann ja die richtige Variante sein.


Nur tritt der von mir beschriebene Fehler immernoch auf...

mkinzler 24. Jun 2010 05:29

AW: Listen und wie man sie nutzt
 
Was spricht den gegen die Verwendung des Delphi-Tags in euren Beiträgen? Bei Delphicode sollte dieser immer verwendet weden

Blup 24. Jun 2010 08:50

AW: Listen und wie man sie nutzt
 
Dir ist schon klar das die Funktion nicht das Element aus der Liste zurückgibt, sondern nur eine Kopie davon? Wird die Funktion aufgerufen wenn die Liste keine Elemente enthält, wird auf jeden Fall eine Zugriffsverletzung auftreten. Ansonsten mit dem Debugger Schritt für Schritt ausführen.

So würde ich das lösen:
Delphi-Quellcode:
type
 PDeveloper = ^TDeveloper;

function getDeveloperByIndex(index: Cardinal): PDeveloper;
begin
  current := first;
  while (index > 0) and Assigned(current) do
  begin
    current := current^.Next;
    Dec(index);
  end;
  if current <> nil then
    Result := @(current^.content)
  else
    Result := nil;
end;
Allerdings ist eine verkettete Liste für Zogriffe über einen Index wenig geeignet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:19 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz