Delphi 有没有办法将整个数组复制到另一个数组中?(使用For循环除外)

Delphi 有没有办法将整个数组复制到另一个数组中?(使用For循环除外),delphi,Delphi,有没有办法将整个数组复制到另一个数组中?而不是使用for循环 or命令对此有效吗? 我确实尝试过,但它有一个错误:不兼容的类型 我应该坚持使用for循环吗?移动或复制将不起作用,您可以使用CopyMemory,但这需要阵列是一个连续的内存块 SetLength(DestArray, Length(MyArray)); CopyMemory(@DestArray[0], @MyArray[0], Length(MyArray) * SizeOf(ArrayElement)); 看 对于索引和Le

有没有办法将整个数组复制到另一个数组中?而不是使用for循环

or命令对此有效吗? 我确实尝试过,但它有一个错误:不兼容的类型


我应该坚持使用for循环吗?

移动或复制将不起作用,您可以使用CopyMemory,但这需要阵列是一个连续的内存块

SetLength(DestArray, Length(MyArray));
CopyMemory(@DestArray[0], @MyArray[0], Length(MyArray) * SizeOf(ArrayElement));

对于索引和LengthSource as count,可以使用copy方法传入0来复制数组,以复制完整内容


对于字符串/数组/接口/etc管理类型的数组,不要使用Move或CopyMemory。这样做将绕过Delphi的引用计数机制,并将导致内存泄漏和数据损坏。

1-如果您的数组不包含任何字符串或动态数组,则可以使用move,但动态数组不能像固定大小的数组那样处理:

var A,B: array[0..10] of integer;
    DA, DB: array of double;
    i: integer;
begin
  for i := low(A) to high(A) do
    A[i] := i;
  move(A[0],B[0],length(A)*sizeof(A[0]));  // first version, compiler does the stuff
  move(A[0],B[0],sizeof(A)); // it works
  move(A[0],B[0],40); // if you know what you're doing, since sizeof(A)=40
  SetLength(DA,10); // DA[0]..DA[9]
  for i := 0 to high(DA) do // or for i := 0 to 9 if you know what you're doing
    DA[i] := 
  SetLength(DB,length(DA)); 
  if length(DA)<=length(DB) then // if your dynamic array may be void, use this before to avoid GPF
    move(DA[0],DB[0],length(DA)*sizeof(DA[0]));
  if pointer(DA)<>nil then // this will just check that DA[] is not void
    move(pointer(DA)^,pointer(DB)^,length(DA)*sizeof(double)); // similar to previous
end;

为了安全起见,在动态数组上使用Copy函数,因为它在内部处理托管类型。数组必须是同一类型,即在同一表达式中声明:

var  
    a, b: array of string;
或者通过定义自定义数组类型:

type   
    TStringArray = array of string;  
var 
    a: TStringArray;  
//...and somewhere else
var  
    b: TStringArray;  
然后你可以做:

a := Copy(b, Low(b), Length(b));  //really clean, but unnecessary 
//...or   
a := Copy(b, 0, MaxInt);  //dynamic arrays always have zero low bound 
                          //and Copy copies only "up to" Count items  
在静态数组和混合数组类型时,必须使用循环,我不建议这样做。 如果您真的必须使用Move,请记住检查长度是否为零,因为A[0]构造可能会引发范围检查错误,SizeOfA[0]是一个值得注意的例外,它由编译器magic处理,从未实际执行过。 另外,千万不要假设A=A[0]或SizeOfA=LengthA*SizeOfA[0],因为这只适用于静态数组,如果您以后试图将庞大的代码库重构为动态数组,它会对您造成严重的影响。

对于动态数组:

var A,B: array of Byte;

begin
  SetLength(A, <size>);
  //initialize A

  B:= A; 
  SetLength(B,Length(A));

end;

在动态数组中,赋值语句仅复制对数组的引用,而SetLength则执行物理复制/复制它的工作,留下两个独立的动态数组

Move使用for循环。至少在Delphi7中是这样。什么代码导致了这个错误?我不知道。移动和复制都导致了错误。我没有同时使用它们,虽然Move没有使用for循环。它是用asm编写的,即使是在Delphi 7中,也可以在Delphi 7中使用rep movsd/movsb,或者在较新的Delphi版本中使用更快的FPU指令。如果数组是相同类型且固定的非动态大小,则可以通过简单地将一个数组指定给另一个数组1:=array2进行复制。不幸的是,它是一个动态数组。但我会把它归档以备将来参考。谢谢DAnd如果数组包含指向托管类型字符串、其他动态数组、接口引用等的指针,则引用计数不会增加。您的意思是移动不总是有效的。它只是将一堆字节从内存中的一个位置复制到另一个位置。这可以很好地移动数组,前提是数组占用连续的内存块。move和CopyMemory在功能上是相同的-唯一的区别是CopyMemory接受指针作为参数,而move接受变量未引用的指针。此外,Delphi数组始终是连续的。虽然使用硬编码的上下界(如0和MaxInt)很方便,但完全忽略边界更方便:a:=Copyb。这复制了整个阵列。@Viktor,你可以与我们的捷克MVP分享CopySource技巧,因为他似乎刚刚发现了省略最后一个参数的可能性。不好意思,我无意中访问了他们的博客。如果你知道你在做什么,因为sizeofA=40,它是44。
var A,B: array of Byte;

begin
  SetLength(A, <size>);
  //initialize A

  B:= A; 
  SetLength(B,Length(A));

end;