2013-06-18 155 views
4

我需要比較給定數組的所有項是否相同。CompareMem適合比較兩個數組是否相等?

現在,我有以下代碼:

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是一種有效的方式來做我想做的事嗎?另外,我想知道,如果將工作的每一個數據類型,如字符串,整數等

+3

使用CompareMem只能使用簡單的數據類型。如果數據是託管類型的,比如對象,字符串,動態數組等,那麼您只是比較指針值。 –

+0

一般答案是** no **,因爲數組元素可能[align](http://docwiki.embarcadero.com/RADStudio/XE4/en/Align_fields_%28Delphi%29)。然而,如果你打算永遠留在Borland編譯器和Intel架構中,你可以安全地做到這一點(這是因爲Borland陣列隱式地被封裝)。 – OnTheFly

回答

4

這不是用匯編...比較存儲器是有效的,如果所有的記憶充滿了數組項無間隙。一般來說,如果

1)所有陣列中的存儲器被填充數據無間隙(間隙可能包含垃圾,並導致假陰性)它將工作。

1.1。這應該由packed array關鍵字強制執行,如果編譯器不會忽略它

1.2如果中SizeOf(A [1])是2,4,8,16等

這應該發生,但你更好地單元蓋此使用不同模式的FillChar進行測試 - 他們會模仿垃圾,然後用匹配的值手工填充數組元素,然後檢查CompareMem元素是否擦除了所有預填充的垃圾。

2)數組元素只包含簡單的值類型,而不包含引用類型。

字符,整數,雙,短字符串,固定大小的數組或製備的那些的記錄 - 是簡單類型。

所有其它字符串,指針,對象,接口,動態和開放的陣列 - 僅僅是用於指向外部數據,並且無法比擬的「由記憶力」

你可以閱讀更多的提示有關http://docwiki.embarcadero.com/Libraries/XE2/en/System.Finalize。的過程/函數彙編實現也將是很好的話題,因爲它會覆蓋不同德爾福數據類型

+0

這不是裝配? – EProgrammerNotFound

+0

你的第二個代碼是程序集,但是你談到你最初引用的代碼是Pascal。那麼,CompareMem正在做它的名字。使PByte變量,並做一個循環比較值和移動兩個指針 - 你會*功能*等效的純粹的pascal代碼。 asm例程只針對速度進行了優化,但基本上可以通過簡單的循環比較字節後的所有字節來實現它的等效。也許你可以從FPC獲得現成的Pure Pascal實現,但它確實很簡單。兩個PByte指針和一個循環 - 就是這樣。 –

+0

這裏是你的功能等同物:http://pastebin.com/HTZDHHxx –

4

CompareMem的二進制表示只是進行逐字節比較字節。有些情況下,CompareMem未能通過值有效,平等的測試主要有兩種方式:

  1. 被測試的類型包含填充。
  2. 正在測試的類型是或包含引用類型。

你問有關數組。由於數組是always packed,它們不包含填充。由於您正在比較數組值,因此問題可以集中在數組的元素上。

當且僅當數組元素是不包含填充字節且不包含引用類型的值類型時,數組的值比較纔是合適的。

這就是所有簡單值類型的情況。

對於記錄,您需要檢查記錄是否包含引用類型。這必須是遞歸檢查。該記錄是否包含包含引用類型的記錄等等。然後你必須尋找填充。一旦發現填充,使用CompareMem是不合適的。

相關問題