5

正如上面的主题所示,我想知道在顺序处理数据时是否有一个干净有效的方法来处理函数参数中传递的指针的好例子。我所拥有的是这样的:

function myfunc(inptr: pointer; inptrsize: longint): boolean;
   var
     inproc: pointer;
     i: integer;
   begin
     inproc := inptr;
     for i := 1 to inptrsize do
       begin
         // do stuff against byte data here.
         inc(longint(inproc), 1);
       end;
   end;

这个想法是,我希望它能够处理任何被推送的东西,而不是有限的数据,无论大小。

现在,在处理数据方面,我想出了几种成功的方法。

  1. 将 parm 指针分配给相同的临时指针,然后使用它们访问每条数据,递增它们以继续。这种方法是最快的,但看起来不是很干净,所有的指针增量都分布在整个代码中。(这就是我上面所说的)
  2. 将 parm 指针分配给表示大数组值的指针,然后使用标准表逻辑递增地处理它。干净得多,但比#1 慢了大约 500 毫秒。

是否有另一种方法可以以这种方式有效地处理指针,或者我是否缺少一些既干净又不会时间效率低的方法?

4

2 回答 2

9

你这里的代码基本上没问题。我总是选择增加一个指针而不是强制转换为一个假数组。

但是您不应该转换为整数。这在语义上是错误的,只要您在指针大小与整数大小不同的平台上编译,您就会付出代价。始终使用指向正确大小元素的指针。在这种情况下,指向字节的指针。

function MyFunc(Data: PByte; Length: Integer): Boolean;
var
  i: Integer;
begin
  for i := 1 to Length do
  begin
    // do stuff against byte data here.
    inc(Data);
  end;
end;

除非编译器遇到了非常糟糕的一天,否则你不会发现比这更容易获得性能更好的代码。更重要的是,我认为这种风格实际上是相当清晰易懂的。大多数清晰度增益来自于避免投射的需要。始终努力从代码中删除强制转换。

如果你想允许传递任何指针类型,那么你可以这样写:

function MyFunc(P: Pointer; Length: Integer): Boolean;
var
  i: Integer;
  Data: PByte;
begin
  Data := P;
  for i := 1 to Length do
  begin
    // do stuff against byte data here.
    inc(Data);
  end;
end;

或者,如果您想避免在接口中使用指针,请使用无类型的 const 参数。

function MyFunc(const Buffer; Length: Integer): Boolean;
var
  i: Integer;
  Data: PByte;
begin
  Data := PByte(@Buffer);
  for i := 1 to Length do
  begin
    // do stuff against byte data here.
    inc(Data);
  end;
end;

如果需要修改缓冲区,请使用 var 参数。

于 2012-12-21T21:44:37.070 回答
2

我有不同的看法:为了可读性,我会使用数组。Pascal 并非设计为能够直接访问内存。原始的帕斯卡甚至没有指针运算。

这就是我使用数组的方式:

function MyFunc(P: Pointer; Length: Integer): Boolean;
var
  ArrayPtr : PByteArray Absolute P;
  I : Integer;

begin
  For I := 0 to Length-1 do 
    // do stuff against ArrayPtr^[I]
end;

但如果性能很重要,我会这样写

function MyFunc(P: Pointer; Length: Integer): Boolean;
var
  EndOfMemoryBlock: PByte;

begin
  EndOfMemoryBlock := PByte(Int_Ptr(Data)+Length);
  While P<EndOfMemoryBlock Do begin
    // do stuff against byte data here.
    inc(P);
  end;
end;
于 2012-12-22T10:29:28.863 回答