Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - offene Array-Parameter als ByValue


Daniel L. - Sa 13.11.10 17:24
Titel: offene Array-Parameter als ByValue
Hi,
ich probiere grade offene Array-Parameter aus.
Dabei übergebe ich einer Routine ByValue ein dynamisches Array, einmal als direkte Variable , und dann als Typvariable.
Innerhalb der Routine manipuliere ich ein Arrayfeld.
Da es sich um dynamische Arrays und somit ja wohl um Zeiger handelt, wäre ich davon ausgegangen, dass in beiden Fällen das eingegebene Array verändert wird (trotz ByValue) und nicht nur das als Typvar übergebene.

Frage: Wo genau liegt der Unterschied?
Gilt das dann auch für andere Typvariablen, oder nur für Arrays?

Danke schon mal für Eure Hilfe,

Gruss: Daniel



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
type

  TDynAr = array of integer;

  TForm1 = class(TForm)
    ...
  procedure test1 (ar : array of integer);
  procedure test2 (ar : TDynAr);
end;


procedure TForm1.test1 (ar: array of integer);
begin
   ar [3] := 123;
end;


procedure TForm1.test2 (ar: TDynAr);
begin
   ar [3] := 123;
end;

...

procedure TForm1.Button1Click (Sender: TObject);
var a1 : array of integer;   //dynamisch
    a2 : TDynAr;             // auch dynamisch
begin
   SetLength (a1, 4);
   a1 [3] := 0;
   test1 (a1);
   showmessage (inttostr (a1 [3]));   // 0

   SetLength (a2, 4);
   a2 [3] := 0;
   test2 (a2);
   showmessage (inttostr (a2 [3]));   // 123
end;


jaenicke - Sa 13.11.10 17:39

Das sind nicht beides "offene Array-Parameter". Das erste ist ein Open Array Parameter. Der wird als Wert übergeben und in der aufgerufenen Funktion kann z.B. die Länge nicht verändert werden.

Das zweite ist ein Dynamic Array Parameter. Sieht genauso aus, ist aber etwas vollkommen anderes. Ein dynamisches Array hat (anders als ein offenes Array) einen Referenzzähler und ist wie auch ein String ein Pointer.

Von der Syntax her ist das also ähnlich, aber eigentlich sind es zwei ganz verschiedene Sachen. Ob das auch bei anderen Typvariablen gilt? Welche meinst du jetzt? Es kommt eben immer auf den Typ an und hier sind es zwei unterschiedliche.


Daniel L. - Sa 13.11.10 21:10

@jaenicke
Aha - da hatte ich was noch nicht kapiert -

Nur noch mal für mich zum Verständnis, lieg ich jetzt richtig?

--"Offene Array-Parameter" können sowohl statische als auch dynamische Arrays sein

--Übergibt man Arrays ByValue via "Offenes Array-Parameter" , wird immer eine Kopie erstellt, egal, ob die Arrays dynamisch oder statisch sind.

Delphi-Quelltext
1:
2:
3:
procedure (a : array of integer) // -- dieses ist ein "offener Array-Parameter"

var b : array of integer:  // b ist ein dynamisches Array


Danke noch mal und G: Daniel


jaenicke - So 14.11.10 05:11

Ja, richtig. Und du kannst da ziemlich viel angeben, sogar einzelne Zahlen (dann ist es ein Array mit einer Zahl, das übergeben wird).

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure Test(a: array of Integer);
var
  i: Integer;
begin
  for i := Low(a) to High(a) do
    ShowMessage(IntToStr(a[i]));
end;

var
  a: array[1..2of Integer;
  b: array of Integer;
  c: Integer;
begin
  Test([34]);

  a[1] := 4;
  a[2] := 45;
  Test(a);

  SetLength(b, 3);
  b[0] := 1;
  b[1] := 2;
  b[2] := 3;
  Test(b[0]);
  Test(b);

  c := 44;
  Test(c);
Sollte so kompilieren und funktionieren.