Si pasa la matriz dinámica como un parámetro que no es var, el compilador realizará una copia.
El siguiente ejemplo de código pequeño demuestra que al mostrar 37/42 en el título del formulario.
procedure IncArray1(data: array of integer);
var i : integer;
begin
for i := Low(data) to High(data) do
data[i] := data[i] + 5;
end;
procedure IncArray2(var data: array of integer);
var i : integer;
begin
for i := Low(data) to High(data) do
data[i] := data[i] + 5;
end;
procedure TForm8.FormCreate(Sender: TObject);
var
data: array of integer;
begin
SetLength(data, 1);
data[0] := 37;
IncArray1(data);
Caption := IntToStr(data[0]);
IncArray2(data);
Caption := Caption + '/' + IntToStr(data[0]);
end;
Si nos fijamos en el código ensamblador generado, IncArray1 comienza con
004552B4 8BCA mov ecx,edx
004552B6 85C9 test ecx,ecx
004552B8 7807 js $004552c1
004552BA 8B1C88 mov ebx,[eax+ecx*4]
004552BD 49 dec ecx
004552BE 53 push ebx
004552BF 79F9 jns $004552ba
004552C1 8BC4 mov eax,esp
Esta matriz de origen código copia a la pila y establece eax a la dirección del primer elemento (= dirección almacenada en el puntero de la pila después del último empujón). La pila crece para que el código comience con el último elemento (edx contiene Alto (datos) cuando se llama IncArray1) y repite (elemento de lectura, elemento de inserción, índice de disminución) hasta llegar al elemento 0.
IncArray2 no contiene tal código. La persona que llama almacena la dirección de los datos en el registro eax antes de llamar a IncArray2 e IncArray2 solo utiliza esta dirección.
En caso de que no desee utilizar 'var' por alguna razón, puede pasar una dirección de los datos a su método. Pero como no puede usar datos de sintaxis:^array of integer 'en la declaración de parámetros, tendrá que declarar un tipo para sus datos. Y tendría que usar 'datos ^' en lugar de 'datos' en todas partes en el método.
type
TData = array of integer;
PData = ^TData;
procedure IncArray(data: PData);
var i : integer;
begin
for i := Low(data^) to High(data^) do
data^[i] := data^[i] + 5;
end;
procedure TForm8.FormCreate(Sender: TObject);
var
data: TData;
begin
SetLength(data, 2);
data[0] := 37;
IncArray(@data);
Caption := IntToStr(data[0]);
end;
probado con Delphi 2007.
Ok, ¿hay alguna manera de hacerlo? Tengo una gran matriz en la que quiero trabajar por referencia. copiar la matriz es muy costoso. – Arthur
Sí, al igual que IncArray2 en el código anterior: prefijo 'var' de usuario. – gabr
@gabr, ¿podría verificar si se copia una matriz dinámica cuando no se muta?Sé que las cadenas son copy-on-write. –