我想知道如何增加FOR循环语句中的值。
这是我的代码。
function Check(var MemoryData:Array of byte;MemorySignature:Array of byte;Position:integer):boolean;
var i:byte;
begin
for i := 0 to Length(MemorySignature) - 1 do
begin
while(MemorySignature[i] = $FF) do inc(i); //<< ERROR <<
if(memorydata[i + position] <> MemorySignature[i]) then Result:=false;
end;
Result := True;
end;
错误是:E2081分配到FOR循环变量'i'。
我正在尝试将旧代码从C#转换为Delphi,但我不能增加'i'。 增加'i'不是唯一的方法,但我想知道问题出在哪里。
答案 0 :(得分:7)
在这种情况下,您可以只执行'继续'而不是inc(i)
答案 1 :(得分:7)
除了Lasse写的内容之外,分配给循环变量通常被认为是代码气味。这使得代码更难以阅读(如果你想要预先离开循环,你可以使用break / continue表达更清晰),并且经常偶然,导致各种令人讨厌的方面 - 效果。因此,在触及循环变量的任何循环中,Borland(现为CodeGear)咬住子弹并将循环变量分配为非法,而不是跳过箍来使编译器不在优化fu上进行优化。
如果你真的想手动使用循环索引,请考虑使用while循环。
答案 2 :(得分:6)
当然其他人(通常)是正确的。没说的是,你的循环中的'i' 不存在 。 Delphi为它使用CPU寄存器。这就是为什么你不能改变它,这就是为什么你应该使用'for'循环(而不是'while'),因为'for'更快。这是你的代码修改(没有测试,但我认为你有这个想法) - 也有imho你有一些错误 - 修复它们:
function Check(var MemoryData:Array of byte;MemorySignature:Array of byte;Position:integer):boolean;
var i:byte;
begin
Result := True; //moved at top. Your function always returned 'True'. This is what you wanted?
for i := 0 to Length(MemorySignature) - 1 do //are you sure??? Perhaps you want High(MemorySignature) here...
begin
if MemorySignature[i] <> $FF then //speedup - '<>' evaluates faster than '='
begin
Result:=memorydata[i + position] <> MemorySignature[i]; //speedup.
if not Result then
Break; //added this! - speedup. We already know the result. So, no need to scan till end.
end;
end;
end;
...还有MemorySignature应该有'const'或'var'。否则就像现在一样,数组被复制了。这意味着每次调用'Check'时减速。拥有'var',代码保持不变,因为AFAIS的MemorySignature没有改变。
HTH
答案 3 :(得分:3)
问题在于编译器采用了原始的FOR循环代码并假设它知道发生了什么,因此它可以通过输出运行速度最快的特定CPU指令来优化代码。
如果它允许你搞乱变量值,那些假设可能会超出窗口,因此代码可能不起作用,这就是为什么它不允许你改变它。
你应该做的只是有一个你实际使用的单独变量,并且只使用FOR循环索引变量来跟踪你当前执行的迭代次数。
作为一个例子,一个典型的优化可能是编写CPU指令,当索引寄存器降至零时将停止迭代,以内部倒计时的方式重写循环,而不是向上,如果你开始弄乱变量,它无法像那样重写代码。
答案 4 :(得分:3)
如果您需要在循环内更改循环计数器,请尝试使用while循环。
顺便说一句,你需要你的 结果:=真 line作为函数的第一行,使其正常工作。实际上,它将始终返回True。答案 5 :(得分:1)
根据Mike Sutton的说法,你需要的是一个while循环,而不是for循环。
function Check(var MemoryData: Array of byte;
MemorySignature: Array of byte; Position: Integer):Boolean;
var
i:byte;
begin
Result := True;
i := 0;
while i < Length(MemorySignature) do
begin
while(MemorySignature[i] = $FF) do
Inc(i);
if(MemoryData[i + position] <> MemorySignature[i]) then
Result := False;
Inc(i);
end;
end;
对“for”的Delphi实现进行了优化,但结果却没有C风格的灵活性