由于它而不会触发的FOR-IN循环';s范围在delphi中不是连续的

由于它而不会触发的FOR-IN循环';s范围在delphi中不是连续的,delphi,for-in-loop,Delphi,For In Loop,经过几天的努力,我的问题变得简单了(只留下重要的部分,请参考我对历史的多次编辑),如下所示: showmessage('i='+inttostr(i)); for i in [2..5,8,11..13] do showmessage('1'); showmessage('i='+inttostr(i)); 这是放在一个单位在我的程序中随机摆弄德尔菲。我想我应该注意到,非连续for-in-loop范围在其他地方(另一个单元)的程序中起作用。总的来说,在同一个过程中,我有两个这样的非连续的for

经过几天的努力,我的问题变得简单了(只留下重要的部分,请参考我对历史的多次编辑),如下所示:

showmessage('i='+inttostr(i));
for i in [2..5,8,11..13] do
showmessage('1');
showmessage('i='+inttostr(i));
这是放在一个单位在我的程序中随机摆弄德尔菲。我想我应该注意到,非连续for-in-loop范围在其他地方(另一个单元)的程序中起作用。总的来说,在同一个过程中,我有两个这样的非连续的
for In循环
,如果我注释掉其中一个,另一个工作正常,但是如果它们都同时处于工作状态,只有第二个工作,第一个工作如下所述

第一个messagebox包含“i=随机数”,因为它未初始化,而不是需要初始化。带有“1”的消息框永远不会出现。出现的第二个messagebox有“i=14”,这意味着循环确实触发了,但没有做任何事情?这太荒谬了,如果没有,如果有人能启发我,我想要两件事:

1) 为什么会这样


2) 如何修复它并在将来避免?

您好,我在Delphi 2006和Xe2上测试了您的代码,在这两种情况下都运行良好;在我看来,可能存在之前的问题,可能是内存被破坏,可能是与变量或复选框数组有关;一旦我有了这样的情况(使用Delphi6),我必须在循环之前初始化J,我做了如下操作:

procedure MyTestFunc();
var
i, j: integer;
begin
  memo1.lines.clear;
  for i:= 1 to 50 do
  Begin
    case i of
      1..10:
        if NOT (somearr[1] as Tcheckbox).checked then
        Begin
            j:=0;
            for j in [2..5,7,11..13] do
            begin
                memo1.Lines.Add('j= '+inttostr(j));
                (somearr[j] as Tcheckbox).Checked := false;
            end
        end
        else memo1.Lines.Add('false');
      11..20:BEgin
           End;
    End;
  End;
end;
我一直都不明白为什么会这样。您始终可以执行逐步调试并检查每个变量

如果您需要更多帮助,您可以发布更多代码,这样我们可以帮助您更好地解决此问题


祝你好运

您好,我在Delphi 2006和Xe2上测试了您的代码,在这两种情况下都运行良好;在我看来,可能存在之前的问题,可能是内存被破坏,可能是与变量或复选框数组有关;一旦我有了这样的情况(使用Delphi6),我必须在循环之前初始化J,我做了如下操作:

procedure MyTestFunc();
var
i, j: integer;
begin
  memo1.lines.clear;
  for i:= 1 to 50 do
  Begin
    case i of
      1..10:
        if NOT (somearr[1] as Tcheckbox).checked then
        Begin
            j:=0;
            for j in [2..5,7,11..13] do
            begin
                memo1.Lines.Add('j= '+inttostr(j));
                (somearr[j] as Tcheckbox).Checked := false;
            end
        end
        else memo1.Lines.Add('false');
      11..20:BEgin
           End;
    End;
  End;
end;
showmessage('i='+inttostr(i));
我一直都不明白为什么会这样。您始终可以执行逐步调试并检查每个变量

如果您需要更多帮助,您可以发布更多代码,这样我们可以帮助您更好地解决此问题

祝你好运

showmessage('i='+inttostr(i));
此时,
i
的随机内存内容恰好位于分配给
i
存储的位置,因为您没有初始化它

for i in [2..5,8,11..13] do
  showmessage('1');
showmessage('i='+inttostr(i));
您的代码中还有其他内容。这在Delphi XE2中运行良好:

procedure TForm2.FormCreate(Sender: TObject);
var
  j: Integer;
begin
  Memo1.Clear;
  for j in [2..5,8,11..13] do
    Memo1.Lines.Add(Format('j = %d', [j]));
end;
以下是
备忘录1
的输出:

你所有的编辑和剩余的杂音太多了,你现在说要忽略它们,很难看出问题出在哪里;你有被剪掉的代码,你正在访问的未声明的变量,还有奇怪的逻辑(不管怎样,从你所包含的内容来看),对我来说是有意义的

我认为您在这方面花费了太多的时间,虽然,当一个非常简单的重写可以帮助您解决问题时(IMO在将来更具可读性和可维护性,但这只是IMO):

就您在另一个循环中看到的
i
count的值从50向下到1而言,在调试器中查看循环计数器时,这是一个已知的问题;它与代码优化有关,这些优化会混淆调试器的计算器。自Delphi 1以来,这是一种众所周知的行为(经常在Borland/CodeGear/Embarcadero新闻组中讨论),并且只影响调试器中的显示;它保证不会影响代码实际执行结果的行为

此时,
i
的随机内存内容恰好位于分配给
i
存储的位置,因为您没有初始化它

for i in [2..5,8,11..13] do
  showmessage('1');
showmessage('i='+inttostr(i));
您的代码中还有其他内容。这在Delphi XE2中运行良好:

procedure TForm2.FormCreate(Sender: TObject);
var
  j: Integer;
begin
  Memo1.Clear;
  for j in [2..5,8,11..13] do
    Memo1.Lines.Add(Format('j = %d', [j]));
end;
以下是
备忘录1
的输出:

你所有的编辑和剩余的杂音太多了,你现在说要忽略它们,很难看出问题出在哪里;你有被剪掉的代码,你正在访问的未声明的变量,还有奇怪的逻辑(不管怎样,从你所包含的内容来看),对我来说是有意义的

我认为您在这方面花费了太多的时间,虽然,当一个非常简单的重写可以帮助您解决问题时(IMO在将来更具可读性和可维护性,但这只是IMO):


就您在另一个循环中看到的
i
count的值从50向下到1而言,在调试器中查看循环计数器时,这是一个已知的问题;它与代码优化有关,这些优化会混淆调试器的计算器。自Delphi 1以来,这是一种众所周知的行为(经常在Borland/CodeGear/Embarcadero新闻组中讨论),并且只影响调试器中的显示;它保证不会影响代码实际执行结果的行为。

可能是您的条件“不”(somearr[1]作为Tcheckbox)。选中“从不计算为true”。请验证在索引1处寻址somearr是否真的是您想要的。能否在j循环之后添加第二条ShowMessage?确认第一条ShowMessage后是否显示?i是什么数据类型,使用什么版本的Delphi,以及启用了什么编译器标志(范围检查、溢出检查)?您的示例在Delphi2007上的效果与我预期的一样。另外,如果在ShowMessage('1')行上放置断点,它是否会命中?如果没有,您能否显示当第一条ShowMessage上的断点命中时CPU窗口的外观?这看起来确实像是您版本的编译器中的代码生成错误。不幸的是,我没有你的版本可供测试,但我在2007年版本中得到的代码是相同的,除了你的语句16“addeax,-$10”,我在这里根本没有,而且没有充分的理由它应该在2010年版本中出现-它基本上在做测试之前从I中减去16。这是理所当然的