Einzelnen Beitrag anzeigen

Roachford
(Gast)

n/a Beiträge
 
#9

Re: Funktionsrückgabewert: Array

  Alt 25. Sep 2008, 14:42
Zitat von oki:
Dynamische Arrays sind imho Zeiger auf Speicherbereiche.
Korrekt.

Zitat von oki:
Das Setzen einer Variable auf nil die ein dynamisches Array hält reicht aus um das Array zu "lösche".
Dabei greift hier Compilermagic von Delphi, welche implizit ein SetLength(x, 0) damit aufruft und zuvor, wenn nötig, das Array finalisiert.

Zitat von oki:
Somit sollte eine Übergabe eines dyn. Arrays in einer Procedure doch die Übergabe eines Zeigers sein. Ist dann überhaupt eine Deklaration als var-Parameter notwendig?
Wenn du var weglässt, erstellt dir Delphi vor Änderungen eine Kopie des Arrays und somit setzt du höchstens die Kopie auf 0.

Mit dem var hingegen legt Delphi dir keine Kopie an sondern übergibt dir den originalen Zeiger auf das Array vom Aufrufer. Somit kannst du das Array auch verändern.

Zitat von oki:
Das es bei der Übergabe von dyn. Arrays in Procedure und Funktionen zum delphiinternen kopieren kommt ist mir so neu. Zur Not habe ich wieder was dazu gelernt.
Ich müsste hier vllt. nochmal explizit darauf hinweisen, dass ich die Veränderung des Arrays meine - also von NIL setzen bist SetLength(). Ein Veränderung der Arrayinhalte ohne Grössenänderung ist natürlich ohne var möglich, da er die Daten an der Stelle direkt editiert, welche der Zeiger bestimmt.

Delphi-Quellcode:
program ArrayTest;

{$APPTYPE CONSOLE}

uses
  Types,
  SysUtils;

procedure ChangeContent(AList: TIntegerDynArray);
var
  i: integer;
begin
  for i := low(AList) to high(AList) do
    AList[i] := 10 - i;
end;

procedure ChangeArray(AList: TIntegerDynArray);
var
  i: integer;
begin
  SetLength(AList, 4);
  for i := low(AList) to high(AList) do
    AList[i] := 50 + i;
end;

procedure Test;
var
  lTestCaller: TIntegerDynArray;
  lInt, i: integer;
begin
  SetLength(lTestCaller, 3);

  for i := low(lTestCaller) to high(lTestCaller) do
    lTestCaller[i] := Succ(i);

  WriteLn('content prior ChangeContent():');
  for lInt in lTestCaller do
    WriteLn(lInt);
  WriteLn;

  ChangeContent(lTestCaller);

  WriteLn('content after ChangeContent() & prior ChangeArray():');
  for lInt in lTestCaller do
    WriteLn(lInt);
  WriteLn;

  ChangeArray(lTestCaller);

  WriteLn('content after ChangeArray():');
  for lInt in lTestCaller do
    WriteLn(lInt);
end;

begin
  try
    Test;

    ReadLn;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Ausgabe:
Zitat von Command Console:
content prior ChangeContent():
1
2
3

content after ChangeContent() & prior ChangeArray():
10
9
8

content after ChangeArray():
10
9
8
  Mit Zitat antworten Zitat