Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dynamische Arrays "zu Fuß" (https://www.delphipraxis.net/13543-dynamische-arrays-zu-fuss.html)

Luckie 20. Dez 2003 20:10

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.

Chewie 20. Dez 2003 20:15

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.

Hansa 20. Dez 2003 20:30

Re: Dynamische Arrays "zu Fuß"
 
Zitat:

Zitat von Chewie
Ja, aber ein Array of Pointer wäre genau so flexibel.

Array of Pointer ? :shock: Was wäre denn das ? Wieder ein Zwischending zwichen Array und Listen/Bäumen. Mit dem Unterschied, daß die Elemente nicht unbedingt gleich sein müssen. Mir dem new und dispose wird lediglich Speicherplatz reserviert/freigegeben, aber dynamisch. Was zu Listen/Bäumen da noch fehlt, ist lediglich noch die Verkettung.

Chewie 20. Dez 2003 20:39

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.

Luckie 20. Dez 2003 21:14

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:

nailor 20. Dez 2003 21:58

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...

Luckie 20. Dez 2003 22:02

Re: Dynamische Arrays "zu Fuß"
 
Zitat:

Zitat von Nailor
Aber falls du die D3Prof-Version hättest, könntest du den TList Code rauskopieren, und kämst auf unter 130 KB...

:zwinker: Was meinst du, was ich gerade gemacht habe mit einer "geliehenen" D5 Enterprise, die ich nicht benutze. Copyright vonBorland noch drüber gesetzt und es sollte OK sein. Musste allerdings selbst noch etwasHand anlegen, damit es ohne SysUtils läuft.

choose 20. Dez 2003 22:18

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:
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;
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.
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 Bei Google sucheniterator pattern und dem Bei Google suchenvisitor pattern erreichen.

Luckie 20. Dez 2003 22:37

Re: Dynamische Arrays "zu Fuß"
 
Zitat:

Zitat von choose
Da Du ohnehin D6 besitzt, würde ich Dir empfehlen, weiterhin dynamische Arrays zu verwenden.

Ja, klar, aber da ich in Erwägung ziehe Programme zu verkaufen und ich dazu eine Professional brauche, wäre das günstigste mir "Delphi for Kids" zu zu legen, wo D3 Prof drin ist und das ganze für 25 Euro. :zwinker: Bisher habe ich noch nichts spezielles aus D6 gebraucht, außer den Dynamischen Arrays. Aber dafür habe ich mir ja jetzt einen Ersatz geschaffen.

w3seek 20. Dez 2003 23:26

Re: Dynamische Arrays "zu Fuß"
 
Hier eine aehnliche Implementierung von TList (allerdings als verkettete liste) von einem sehr alten projekt von mir:

Delphi-Quellcode:
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;
[edit=Luckie]Wir haben Delphi-Tags. :zwinker: Mfg, Luckie[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:05 Uhr.
Seite 2 von 4     12 34      

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