Nếu bạn chuyển mảng động dưới dạng tham số không phải var, trình biên dịch sẽ tạo một bản sao.
Mẫu mã nhỏ bên dưới cho thấy rằng bằng cách hiển thị 37/42 trong chú thích biểu mẫu.
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;
Nếu chúng ta nhìn vào mã lắp ráp tạo ra, IncArray1 bắt đầu với
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
mảng nguồn sao chép mã này vào stack và đặt eax đến địa chỉ của phần tử đầu tiên (= địa chỉ được lưu trữ trong ngăn xếp con trỏ sau lần đẩy cuối cùng). Stack phát triển xuống để mã bắt đầu với phần tử cuối cùng (edx chứa Cao (dữ liệu) khi IncArray1 được gọi) và lặp lại (phần tử đọc; phần tử đẩy; chỉ mục giảm) cho đến khi nó đến phần tử 0.
IncArray2 không chứa mã như vậy. Người gọi lưu trữ địa chỉ của dữ liệu vào thanh ghi eax trước khi gọi IncArray2 và IncArray2 chỉ sử dụng địa chỉ này.
Trong trường hợp bạn không muốn sử dụng 'var' vì bất kỳ lý do gì, bạn có thể chuyển địa chỉ của dữ liệu cho phương pháp của mình. Nhưng vì bạn không thể sử dụng cú pháp 'data:^array of integer' trong khai báo tham số, bạn phải khai báo một kiểu cho dữ liệu của bạn. Và bạn phải sử dụng 'dữ liệu ^' thay vì 'dữ liệu' ở mọi nơi trong phương thức.
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;
Thử nghiệm với Delphi 2007.
Ok vậy có cách nào để làm điều đó, tôi có một mảng lớn mà tôi muốn làm việc trên thông qua tham chiếu. sao chép mảng là xa để comptationaly đắt tiền. – Arthur
Có, giống như IncArray2 thực hiện trong đoạn mã trên - tiền tố 'var' của người dùng. – gabr
@gabr, bạn có thể kiểm tra xem mảng động có được sao chép khi bạn không biến đổi không?Tôi biết rằng các chuỗi là copy-on-write. –