我试图将RefPack压缩实现移植到Delphi,但我很难理解代码的某些部分:
hashtbl = NEW int32[65536];
link = NEW int32[131072];
hashptr = hashtbl;
for (i=0; i<65536L/16; ++i)
{
*(hashptr+0) = *(hashptr+1) = *(hashptr+2) = *(hashptr+3) =
*(hashptr+4) = *(hashptr+5) = *(hashptr+6) = *(hashptr+7) =
*(hashptr+8) = *(hashptr+9) = *(hashptr+10) = *(hashptr+11) =
*(hashptr+12) = hashptr[13] = hashptr[14] = hashptr[15] = -1L;
hashptr += 16;
}
下面是我的代码:
var
hashtbl: PUInt32;
hashptr: PUInt32;
GetMem(hashtbl, 65536);
GetMem(link, 131072);
hashptr := hashtbl;
for I := 0 to (65536 div 16) - 1 do
begin
?!?
hashptr := hashptr + 16;
end;
问题1:"65536 l"这是什么?意味着什么?
问题2:我不知道循环内的代码是什么,以及如何将其转录到Delphi…有人能开导我一下吗?
Ps:我正在使用Delphi Community Edition.
在c++中,整数字面值可以包含一个后缀来指定该字面值的数据类型。在本例中,L
后缀表示long
。Delphi没有这样的后缀,但您可以使用类型化常量来代替。
在c++中,赋值操作符=
返回对被赋值对象左侧变量的引用。该引用可以在后续表达式中使用。因此,c++中的表达式*(hashptr+0) = *(hashptr+1) = ... = hashptr[14] = hashptr[15] = -1L;
意味着将-1
赋值给hashptr[15]
,然后将hashptr[15]
赋值给hashptr[14]
,以此类推,直到将*(hashptr+1)
赋值给*(hashptr+0)
。Delphi不支持,你必须将这样的表达式拆分为单独的语句。
在c++中,表达式*(hashptr+N)
和hashptr[N]
是相同的。它们都使hashptr
指针增加N
个元素,然后对结果解引用以访问所指向的元素。
因此,将所有内容放在一起,c++代码只是循环遍历hashtbl
数组,将每个元素设置为-1
,每次循环迭代16个元素。一个简单的文字c++代码到Delphi的翻译看起来像这样:
{$POINTERMATH ON}
var
hashtbl, link, hashptr: PInt32;
i: Integer;
...
GetMem(hashtbl, SizeOf(Int32) * 65536);
GetMem(link, SizeOf(Int32) * 131072);
hashptr := hashtbl;
for i := 0 to (65536 div 16)-1 do
begin
(hashptr+0)^ := -1;
(hashptr+1)^ := -1;
(hashptr+2)^ := -1;
(hashptr+3)^ := -1;
(hashptr+4)^ := -1;
(hashptr+5)^ := -1;
(hashptr+6)^ := -1;
(hashptr+7)^ := -1;
(hashptr+8)^ := -1;
(hashptr+9)^ := -1;
(hashptr+10)^ := -1;
(hashptr+11)^ := -1;
(hashptr+12)^ := -1;
hashptr[13] := -1;
hashptr[14] := -1;
hashptr[15] := -1;
Inc(hashptr, 16);
end;
...
FreeMem(link);
FreeMem(hashtbl);
可以大大简化:
var
hashtbl, link: array of Int32;
i, j: Integer;
...
SetLength(hashtbl, 65536);
SetLength(link, 131072);
for i := 0 to (65536 div 16)-1 do
begin
for j := 0 to 15 do begin
hashtbl[(i*16)+j] := -1;
end;
end;
...
或简单的:
var
hashtbl, link: array of Int32;
i, j: Integer;
...
SetLength(hashtbl, 65536);
SetLength(link, 131072);
for i := 0 to 65535 do
begin
hashtbl[i] := -1;
end;
...
L
后缀代表long
。-1L
是一个long
常量(或者在你的例子中是二进制32)。
第二部分将hashtbl
数组的每个元素设置为-1
。它以16个元素为块。
for I := 0 to 65535 do
begin
hashtbl[I] := -1;
end;