2016-12-28 50 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。 –