Autor Beitrag
Daniel L.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 140
Erhaltene Danke: 14

W7, W8
TurboD Prof, Delphi Community
BeitragVerfasst: Sa 13.11.10 17:24 
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


ausblenden volle Höhe 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 140
Erhaltene Danke: 14

W7, W8
TurboD Prof, Delphi Community
BeitragVerfasst: 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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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).
ausblenden 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.