定义自定义类型变量 -> 复制自定义类型定义数组 - Delphi XE3



我想知道是否有人可以指出对数组使用两种不同的复制方法(定义为类型(时有什么区别。

我需要创建一个函数来对动态数组中整数的元素进行排序,从最小到最大或从最大到最小。因此,我创建了一个这样的新类型:

type IntArray = array of integer;

然后我定义了一个要排序的函数,有两个方向,由整数传递标识,参数为 0 以向最小值(最大 -> 分钟(排序,或 1 以向最大值(最小 -> 最大值(排序。

function SortArray(ToSort: IntArray; Direction: integer): IntArray;
var count, i: integer;
Label Label1, Label2;
begin
count:=Length(ToSort);
if (Direction = 1) then
  begin
    Label1:
    for i := 0 to count-2 do
      begin
        if ToSort[i+1] > ToSort[i] then
          begin
            ToSort[i+1]  :=ToSort[i]   +ToSort[i+1];
            ToSort[i]    :=ToSort[i+1] -ToSort[i];
            ToSort[i+1]  :=ToSort[i+1] -ToSort[i];
            GoTo Label1;
          end;
      end;
  end
else
if (Direction = 0) then
  begin
    Label2:
    for i := 0 to count-2 do
      begin
        if ToSort[i+1] < ToSort[i] then
          begin
            ToSort[i+1]  :=ToSort[i]   +ToSort[i+1];
            ToSort[i]    :=ToSort[i+1] -ToSort[i];
            ToSort[i+1]  :=ToSort[i+1] -ToSort[i];
            GoTo Label2;
          end;
      end;
  end;
Result:=ToSort;

现在,这个函数看起来工作得很好,但是关于我如何定义传递给函数调用的数组,结果有所不同;

我有一个按钮的 OnClick 事件,它给出了两个函数调用:

procedure Button1Click(Sender: TObject);
var a, b: IntArray;
  i: Integer;
begin
SetLength(a, 10);
SetLength(b, 10);
for i := 0 to 9 do
  begin
    a[i]:=Random(100);      
    b[i]:=a[i];             // Example 1;
  end;
// b:=a;                    // Example 2;
a:=SortArray(a, 1);
b:=SortArray(b, 0);
for i := 0 to 9 do
  begin
    Listbox1.Items.Add(InttoStr(a[i]));
    Listbox2.Items.Add(InttoStr(b[i]));
  end;
end;

现在的问题是,如果我按照示例 1 中提供的方式定义数组 B,>函数工作正常。A 按最大值排序,而 B 按最小值排序;

但是,如果我按照示例 2 中提供的方式定义数组 B,->该函数为两次调用提供了相同的结果,两者都是按最大值排序的数组(如第一次调用中调用的那样(。

为什么我定义数组 b 的方式有所不同,为什么我不应该直接将其作为 var 复制到 var?在这一点上对我来说似乎没有多大意义...

在示例 1 中,您循环访问并将 a 中的每个元素的值分配给 b 中的相应插槽。您有两个单独的数组,具有完全独立的内容。

b[i] := a[i];

因此,排序适用于每个独立数组,并且事情按预期工作。您可以通过将它们设置为不同的值,然后检查元素以确认它们实际上不同来验证这一点:

a[0] := 1;
b[i] := 2;   // Inspecting shows a[0] <> b[0].

在示例 2 中,您将b设置为指向 a ,这意味着访问b[1]实际上是访问与 a[1] 相同的内存位置。你只有一个数组(a(,有两个对它的引用(ab(。排序实际上是在单个数组上工作,因此您所做的只是首先按升序对数组进行排序,然后按降序对同一数组进行排序(通过第二个引用(,并且您不会得到预期的结果。

您可以通过再次将它们设置为不同的值,然后检查元素来确认这一点,但这次它们将是相同的值:

b := a;
a[0] := 1;
b[0] := 2;      // Both a[0] and b[0] now contain the value 2.

最新更新