2016-12-28 18 views
2

在Delphi數組的數組,我宣佈一個3x3矩陣表作爲單一的數組的數組,像這樣: 內存複製和內存比較單一

m_Table: array [0..2] of array [0..2] of Single; 

現在我想的內存比較與內容另一個表或內存複製另一個表中的表內容。我知道我可以創建一個嵌套循環來做到這一點,但如果可能的話,我想在沒有任何循環的情況下完成這項工作。

我的問題是,它是正確的複製或比較喜歡這樣的記憶:

CompareMem(m_Table, other.m_Table, 9 * SizeOf(Single)); 
CopyMemory(m_Table, other.m_Table, 9 * SizeOf(Single)); 

如果沒有,什麼是做正確的方法是什麼?

作爲一個輔助問題,有沒有更好的方法來獲得長度來複制,而不是9 * SizeOf(Single),比如,中SizeOf(m_Table ^)?

Regards

回答

5

問題中的代碼正常工作。我個人認爲Move是複製內存的慣用方法。此外,我會使用SizeOf(m_Table)來獲取類型的大小。

我會指出你的比較不同於浮點相等運算符。也許這就是你想要的,但你應該意識到這一點。例如零和負零比較使用浮點比較相等,但不與內存比較。 NaN總是比較不相等,即使是相同的位模式。

讓我也評論一下,如果你爲這些矩陣聲明瞭一個類型,它會使你的代碼更加可擴展。沒有這些,你將無法編寫接受這些對象的函數。

5

正確的和最簡單的方法可能是定義一個類型:

type 
    TMatrix3x3 = array [0..2,0..2] of Single; 

然後你就可以直接寫:

var 
    v1, v2: TMatrix3x3; 
begin 
    fillchar(v1,sizeof(v1),0); 
    move(v1,v2,sizeof(v1)); 
    if comparemem(@v1,@v2,sizeof(v1)) then 
    writeln('equals'); 
end; 

使用sizeof()使你的代碼的安全性和可讀性。

你可以定義一個包裝類型與方法:如果需要

{ TMatrix3x3 } 

type 
    TMatrix3x3 = record 
    v: array [0..2,0..2] of Single; 
    procedure Zero; 
    procedure Copy(var dest: TMatrix3x3); 
    procedure Fill(const source: TMatrix3x3); 
    function Equals(const other: TMatrix3x3): boolean; 
    end; 

procedure TMatrix3x3.Copy(var dest: TMatrix3x3); 
begin 
    move(v,dest,sizeof(v)); 
end; 

function TMatrix3x3.Equals(const other: TMatrix3x3): boolean; 
begin 
    result := CompareMem(@v,@other.v,sizeof(v)); 
end; 

procedure TMatrix3x3.Fill(const source: TMatrix3x3); 
begin 
    move(source,v,sizeof(v)); 
end; 

procedure TMatrix3x3.Zero; 
begin 
    fillchar(v,sizeof(v),0); 
end; 

包括當時先進的功能,如隱式分配,和運營商。

但是不要重新發明輪子,如果你真的要使用矩陣算術。使用已經存在且經過充分測試的庫,這將爲您節省很多麻煩和調試時間。

+0

至於現有的圖書館,我懷疑有好的有這樣的類型。我知道我已經把我所有的例程都推出了這種類型。 –

+1

答案中增強記錄的一些問題。您提出了方法主題的變異方法。這是記錄問題。當你在一個const參數中調用這樣一個方法時,會導致語義錯誤。如果內存不可寫,甚至運行時錯誤。記錄上沒有變異方法。使用返回值的靜態類函數。等號運算符在沒有不等於的情況下有點無用。此外,二進制比較與浮點比較不同。這是微妙但重要的。 –

+1

此外,您的複製和填充方法可以被刪除,並在他們的地方使用':='賦值運算符使用簡單的舊的。如果你想設置爲零,那麼最好的方法是用該值聲明一個類型常量並使用賦值。 –

1

必須使用標準TMatrix類型從System.Math.Vectors單元,那麼你可以直接比較它if Matrix1 = Matrix2 then和指定爲Matrix1 := Matrix2

+0

你在那裏做了一個很大的假設。該RTL類型用於2D空間。但是提問者可能會對3D定位矩陣感興趣。 –

+1

@DavidHeffernan問題明確的是關於3x3矩陣 – EugeneK

+0

而你引用的類型是2D空間。我的3x3矩陣用於3D空間。你不知道這種類型是否合適。你不能分辨這種類型是2D還是3D。 –