Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays CompareMem是否适合比较两个数组是否相等?_Arrays_Delphi_Compare - Fatal编程技术网

Arrays CompareMem是否适合比较两个数组是否相等?

Arrays CompareMem是否适合比较两个数组是否相等?,arrays,delphi,compare,Arrays,Delphi,Compare,我需要比较给定数组的所有项是否相同 目前,我有以下代码: Type TD = array [0..1] of TDateTime; var A: TD; B: TD; begin A[0] := Date-1; A[1] := Date+1; B[0] := Date-1; B[1] := Date+1; if CompareMem(@A, @B, SizeOf(TD)) then Showmessage('Equals') else Sh

我需要比较给定数组的所有项是否相同

目前,我有以下代码:

Type
  TD = array [0..1] of TDateTime;

var A: TD;
    B: TD;
begin
  A[0] := Date-1;   A[1] := Date+1;
  B[0] := Date-1;   B[1] := Date+1;

  if CompareMem(@A, @B, SizeOf(TD)) then
    Showmessage('Equals')
  else
    Showmessage('Differ');
这很好,但由于CompareMem是在汇编中编写的,所以我还不能理解它的作用


CompareMem是我想要的一种有效方法吗?另外,我还想知道它是否适用于所有数据类型,如字符串、整数等。

这不是在汇编中编写的。。。如果所有内存都被无间隙的数组项填充,则比较内存是有效的。一般来说,如果

1) 所有阵列内存都充满了没有间隙的数据(间隙可能包含垃圾并导致误报)

1.1。若编译器不忽略它,则应通过
压缩数组
关键字强制执行此操作

1.2如果SizeOf(A[1])为2,4,8,16等,则应发生这种情况

但是,最好通过使用具有不同模式的FillChar进行单元测试来解决这个问题——它们将模拟垃圾,然后用匹配的值手动填充数组元素,然后使用CompareMem检查元素是否清除了所有预先填充的垃圾

2) 数组元素只包含简单的值类型,而不包含引用类型

Char、integer、double、short string、固定大小数组或由它们组成的记录都是简单的类型

所有其他字符串、指针、对象、接口、动态数组和开放数组都只是指向外部数据的指针,不能“按内存”进行比较


您可以阅读更多提示。程序/函数的汇编程序实现也是一个很好的主题,因为它将涵盖不同Delphi数据类型的二进制表示形式

compareM
只执行逐字节比较。有两种主要方式使得
CompareMem
无法通过值进行相等性测试:

  • 正在测试的类型包含填充
  • 正在测试的类型是或包含引用类型
  • 您正在询问有关数组的问题。由于数组是空的,所以它们不包含填充。因为要比较数组值,所以问题可以集中在数组的元素上

    当且仅当数组元素是不包含填充字节和引用类型的值类型时,数组的值比较才是合适的

    这是所有简单值类型的情况


    对于记录,您需要检查记录是否包含引用类型。这必须是一个递归检查。记录是否包含包含引用类型的记录,等等。然后你必须寻找填充物。一旦找到填充,使用
    CompareMem
    就不合适了。

    您的第二个代码是assembly,但您提到了您最初引用的代码,该代码过去是Pascal,现在是Pascal。好吧,CompareMem正在做它名下的事情。生成PByte变量并进行循环,比较值并移动两个指针,这样就得到了功能等效的纯pascal代码。asm例程只是在速度方面进行了非常优化,但基本上,您可以通过简单的循环逐个字节地比较来实现其等效功能。也许您可以从FPC获得现成的纯Pascal实现,但它实际上是微不足道的。两个PByte指针和一个循环-就是这样。所以,使用字符串数组执行此操作的唯一方法是对循环中的每个项执行比较?是的。你可以通过预先计算字符串的哈希值和存储hash+string而不是单独存储字符串来加快速度——在某些任务中可以提高速度,但在其他任务中则不行。你关于填充的讨论是有缺陷的。Delphi数组总是打包的。但记录可能不是这样。当它们不存在时,比较内存就不起作用,因为比较的是没有意义的填充字节。而且,记录不是简单的类型。记录是结构化类型。使用CompareMem只能处理简单的数据类型。若数据是托管类型,比如对象、字符串、动态数组等,那个么您只是在比较指针值。一般的答案是否定的,因为数组元素可能是。但是,如果您打算永远使用Borland编译器和Intel体系结构,您可以安全地使用它(这是因为Borland阵列是隐式的
    压缩的
    )。