正如上面的主题所示,我想知道在顺序处理数据时是否有一个干净有效的方法来处理函数parms中传递的指针的好例子。我所拥有的是:
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;
我的想法是,不管有多大的数据,我希望它能够处理任何被推送的内容,而不是有限的数据。
现在谈到处理数据时,我已经想出了几种成功的方法。
有没有其他方法可以通过这种方式有效地处理处理指针,或者是否有一些我缺少的方法既干净又不缺时?
答案 0 :(得分:9)
这里的代码基本上没问题。我总是选择增加指针而不是强制转换为假数组。
但是你不应该转换为整数。这在语义上是错误的,只要您在指针大小与整数大小不同的平台上编译,您就会支付罚金。始终使用指向正确大小的元素的指针。在这种情况下,指向byte。
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参数。
答案 1 :(得分:2)
我有不同意见:为了便于阅读,我会使用一个数组。 Pascal的设计不能直接访问内存。原始的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;