【问题标题】:Defining custom type vars -> Copying custom type defined array - Delphi XE3 [duplicate]定义自定义类型变量->复制自定义类型定义的数组-Delphi XE3 [重复]
【发布时间】:2014-12-07 23:43:54
【问题描述】:

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

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

type IntArray = array of integer;

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

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? 在这一点上对我来说似乎没有多大意义......

【问题讨论】:

  • 这在文档docwiki.embarcadero.com/RADStudio/en/…中有解释 开始阅读“if X and Y ...”
  • 如果你有一个指针,那么赋值复制引用。例如,分配不会复制类实例。字符串是例外。
  • 字符串具有写时复制 (COW) 机制,因此它们与其他引用类型不同。
  • 虽然代码有很多问题。不必要的重复。您可以在同一代码中同时进行增加和减少,但只需打开比较即可。您需要了解布尔值。您的交换技术不透明且晦涩难懂。使用温度。 Goto 是不必要的,应该避免。 You sort 是一种低效的冒泡排序类型。 TArray&lt;Integer&gt; 是整数的 dyn 数组。另外,delphi 已经自带排序功能了。
  • 所以,这是你的排序函数:docwiki.embarcadero.com/Libraries/en/…

标签: delphi delphi-xe3


【解决方案1】:

在示例 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),有两个引用(a 和b)。排序实际上是在单个数组上工作,所以您所做的只是首先按升序对数组进行排序,然后按降序对同一数组(通过第二个引用)进行排序,但您不会得到您期望的结果。

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

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

【讨论】:

    猜你喜欢
    • 2021-04-21
    • 2011-06-30
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多