如何在FOR循环语句中增加FOR循环值?

时间:2009-07-09 17:56:26

标签: delphi

我想知道如何增加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'不是唯一的方法,但我想知道问题出在哪里。

6 个答案:

答案 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风格的灵活性