Timm Thaler hat geschrieben:Wie ist das eigentlich bei dynamischen Arrays: Wenn ich in einer Prozedur ein statisches Array datenbuffer : array[0..max] of real habe und das per LoadData(datenbuffer); an eine Prozedur übergebe, die mit procedure LoadData(var daten : array of real); deklariert ist, ist ja daten ein dynamisches Array von datenbuffer. Daten, die ich da reinschreibe, stehen nach Ende der Prozedur auch in datenbuffer.
Wird dabei ein neues Array daten angelegt und die Daten aus datenbuffer da rein und am Ende der Prozedur wieder zurückkopiert? Oder wird nur ein Zeiger auf datenbuffer übergeben? Was nebenbei eine vernünftige Erklärung wäre, warum die dynamischen Arrays immer bei Null anfangen.
Der Parameter ist immer noch ein Offenes Array und kein Dynamisches, Technisch wird es realisiert wie ein Statisches Array (also der Speicherblock der übergeben wird hat eine feste unveränderbare Länge, welche beim Aufruf feststehen muss), darum lassen sich Statische Arrays sehr leicht (implizit) in Offene Überführen, Dynamische Arrays allerdings nicht (grad gesehen: nur in Delphi, fpc konvertiert dir auch einen Dynamisches Array implizit). Wenn du nun das ganze als Referenz (var keyword) übergibst, so wird intern nur ein Zeiger auf das erste Element deines Statischen Arrays übergeben. (entspricht damit also der value übergabe eines Dynamischen arrays).
Es ist allerdings nicht so ganz wie ein Dynamisches Array, da ein Dynamisches Array sich da durch auszeichnet dass man SetLength aufrufen kann, was ja (logischerweise) nicht funktioniert
Wenn du einen Statischen Array einem Offenen Array per Value übergibst, so wird der gesamte Array bei der Übergabe kopiert, und ist dann im parameter als offenes Array 0 basiert, unabhängig von den ursprünglichen Arraygrenzen.
Außerdem kann man auch Teilarrays übergeben:
Code: Alles auswählen
procedure foo(arr: array of Byte);
...
var arr: Array[0..10] of Byte;
...
foo(arr[1..5]); // übergibt einen array der Größe 5 mit den Elementen 1-5 des arrays arr
Dynamische Arrays fangen bei 0 an, damit sie mit der Zeigerarithmetik übereinstimmen, damit funktioniert dieser tolle Code:
Code: Alles auswählen
var p: PInteger;
i: Integer;
begin
p:=GetMem(5*SizeOf(integer));
for i:=0 to 4 do
p[i] := i;
FreeMem(p);
end.
Da Dynamische Arrays somit Äquivalent zu Zeigern auf ein Array sind