![]() |
Re: Dynamische Arrays "zu Fuß"
Flexibeler in dem Sinne, da ich einen Zeiger auf einen Record habe, kann ich so viele Felder wie ich will in dem Record haben. In dem Sinne hätte man ein mehrdimensionales Array.
|
Re: Dynamische Arrays "zu Fuß"
Ja, aber ein Array of Pointer wäre genau so flexibel.
Abgesehen von den Vor- oder Nachteilen, die eine Klassenimplementierung mit sich bringt, natürlich. |
Re: Dynamische Arrays "zu Fuß"
Zitat:
|
Re: Dynamische Arrays "zu Fuß"
Ein Array ist eine Liste, allerdings eine sequenzielle. Ob der Datentyp Pointer, Integer oder Mohnbrötchen ist, spielt überhaupt keine Rolle. Ein Array mit Datentyp Pointer hat auch nicht mehr (oder weniger) zu tun mit einer verketteten Liste. Dort kannst du ja als Datentyp bei dem Wert Pointer angeben.
|
Re: Dynamische Arrays "zu Fuß"
Verdammt. TList ist in Classes drin. Das kann ich ja nun gar nicht brauchen, wen ich ohne VCL programmiere, das sind gleich wieder 130 KB mehr. :evil:
|
Re: Dynamische Arrays "zu Fuß"
Aber falls du die D3Prof-Version hättest, könntest du den TList Code rauskopieren, und kämst auf unter 130 KB...
|
Re: Dynamische Arrays "zu Fuß"
Zitat:
|
Re: Dynamische Arrays "zu Fuß"
Hallo Luckie,
der Nachteil bei Lösungen, die generisch mit Pointern arbeiten (zB TList) liegt in der fehlenden Fähigkeit, mit Typen zu arbeiten. Der Nachteil von Verketteten Listen liegt in dem relativ hohen Aufwand der Verwaltung. Die Folgende Lösung habe ich zu DOS-Zeiten häufig verwendet:
Delphi-Quellcode:
der Nachteil ist, dass Du das Ausmaß des Arrays nicht unmittelbar über Low und High ermitteln kannst (es muss zusätzlich, zB in einem Record, die Größe festgehalten werden) und die Indexberechnung bei höherdimensionalen Arrays nur dann funktioniert, wenn die "inneren" Dimensionen fest sind.
procedure TForm1.Button1Click(Sender: TObject);
type TMyType = Integer; TMyArray = array[0..MaxInt div SizeOf(TMyType)-1] of TMyType; PMyArray = ^TMyArray; var myArray : PMyArray; mySize : Integer; begin mySize:= 137*42; GetMem(myArray, SizeOf(TMyType)*mySize); try myArray^[0]:= 1; myArray^[1]:= 2; myArray^[2]:= myArray^[0]+myArray^[1]; finally FreeMem(myArray); end; end; Darüber hinaus musst Du (wie bei den anderen Lösungen) die Speicherverwaltung selbst implementieren musst (um Gegensatz zu dynamischen Arrays, bei denen eine transparente Referenzzählung vom Compiler übernommen wird). Da Du ohnehin D6 besitzt, würde ich Dir empfehlen, weiterhin dynamische Arrays zu verwenden. Falls Du mit Klassen arbeitest, könntest Du eine Lösung, die typensicher ist, mit dem ![]() ![]() |
Re: Dynamische Arrays "zu Fuß"
Zitat:
|
Re: Dynamische Arrays "zu Fuß"
Hier eine aehnliche Implementierung von TList (allerdings als verkettete liste) von einem sehr alten projekt von mir:
Delphi-Quellcode:
[edit=Luckie]Wir haben Delphi-Tags. :zwinker: Mfg, Luckie[/edit]
type
{ **************************************************************************** * TList * **************************************************************************** } PListItem = ^TListItem; TListItem = record Data: Pointer; Prev: PListItem; Next: PListItem; end; TList = class private FStart: PListItem; FEnd: PListItem; FCount: Integer; FCurrent: PListItem; public constructor Create; destructor Destroy; override; procedure Clear; procedure Add(Data: Pointer); function Count: Integer; function GetItem(Index: Integer): Pointer; procedure SetItem(Index: Integer; Data: Pointer); function Remove(Data: Pointer): Boolean; function Delete(Index: Integer): Boolean; procedure BeginWalk; procedure BeginWalkEnd; function Walk(var Data: Pointer): Boolean; function WalkBack(var Data: Pointer): Boolean; function GetCurrent(var Data: Pointer): Boolean; function SetCurrent(Data: Pointer): Boolean; function IndexOf(Data: Pointer): Integer; end; { **************************************************************************** * TList * **************************************************************************** } constructor TList.Create; begin inherited Create; FStart := nil; FEnd := nil; FCount := 0; FCurrent := nil; end; destructor TList.Destroy; begin try Clear; finally inherited Destroy; end; end; procedure TList.Clear; var Current: PListItem; Next: PListItem; begin Current := FStart; while Current <> nil do begin Next := Current^.Next; try Dispose(Current); finally Current := Next; end; end; FStart := nil; FEnd := nil; FCount := 0; FCurrent := nil; end; procedure TList.Add(Data: Pointer); var item: PListItem; begin New(item); item^.Data := Data; if (FEnd = nil) or (FStart = nil) then begin item^.Prev := nil; item^.Next := nil; FStart := item; FEnd := item; end else begin FEnd^.Next := item; item^.Next := nil; item^.Prev := FEnd; FEnd := item; end; Inc(FCount); end; function TList.Count: Integer; begin Result := FCount; end; function TList.GetItem(Index: Integer): Pointer; var x: Integer; item: PListItem; begin item := FStart; for x := 1 to Index do begin if item = nil then begin Break; end; item := item^.Next; end; if item = nil then begin Result := nil; end else begin Result := item^.Data; end; end; procedure TList.SetItem(Index: Integer; Data: Pointer); var x: Integer; item: PListItem; begin item := FStart; for x := 1 to Index do begin if item = nil then begin Break; end; item := item^.Next; end; if item <> nil then begin item^.Data := Data; end; end; function TList.Remove(Data: Pointer): Boolean; var item, next: PListItem; begin Result := false; item := FStart; while item <> nil do begin next := item^.Next; if item^.Data = Data then begin if item^.Prev <> nil then begin item^.Prev^.Next := next; if next <> nil then begin next^.Prev := item^.Prev; end else begin FEnd := item^.Prev; item^.Prev^.Next := nil; end; end else begin FStart := next; if next <> nil then begin next^.Prev := nil; end else begin FEnd := item; end; end; try Dec(FCount); if item = FCurrent then begin if FCurrent <> nil then begin FCurrent := FCurrent^.Prev; end; end; Dispose(item); finally Result := true; end; Break; end; item := next; end; end; function TList.Delete(Index: Integer): Boolean; var item, next: PListItem; x: Integer; begin Result := false; item := FStart; x := 0; while (item <> nil) and (x <= Index) do begin next := item^.Next; if x = Index then begin if item^.Prev <> nil then begin item^.Prev^.Next := next; if next <> nil then begin next^.Prev := item^.Prev; end else begin FEnd := item^.Prev; item^.Prev^.Next := nil; end; end else begin FStart := next; if next <> nil then begin next^.Prev := nil; end else begin FEnd := item; end; end; try Dec(FCount); if item = FCurrent then begin if FCurrent <> nil then begin FCurrent := FCurrent^.Prev; end; end; Dispose(item); finally Result := true; end; Break; end; item := next; Inc(x); end; end; procedure TList.BeginWalk; begin FCurrent := FStart; end; procedure TList.BeginWalkEnd; begin FCurrent := FEnd; end; function TList.Walk(var Data: Pointer): Boolean; begin Result := FCurrent <> nil; if Result then begin Data := FCurrent^.Data; FCurrent := FCurrent^.Next; end; end; function TList.WalkBack(var Data: Pointer): Boolean; begin Result := FCurrent <> nil; if Result then begin Data := FCurrent^.Data; FCurrent := FCurrent^.Prev; end; end; function TList.GetCurrent(var Data: Pointer): Boolean; begin Result := FCurrent <> nil; if Result then begin Result := FCurrent^.Prev <> nil; if Result then begin Data := FCurrent^.Prev^.Data; end else begin Data := FCurrent^.Data; end; end; end; function TList.SetCurrent(Data: Pointer): Boolean; begin Result := FCurrent <> nil; if Result then begin Result := FCurrent^.Prev <> nil; if Result then begin FCurrent^.Prev^.Data := Data; end else begin FCurrent^.Data := Data; end; end; end; function TList.IndexOf(Data: Pointer): Integer; var item: PListItem; x: Integer; begin Result := -1; x := 0; item := FStart; while item <> nil do begin if item^.Data = Data then begin Result := x; Break; end; Inc(x); item := item^.Next; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:05 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