【问题标题】:Increment an integer variable in a loop在循环中增加一个整数变量
【发布时间】:2013-05-01 21:39:16
【问题描述】:

我有一个整数变量“i”,我想做一个循环,将“i”从 40000 增加到 90000,每次加 1000。每个结果都会出现在一个 ComboBox 中。

示例:40000 - 41000 - 42000 - 43000 - ... - 88000 - 89000 - 90000

我的代码如下:

var i:integer;
begin
 for i:= 40000 to 90000 do
  begin
   ComboBox1.AddItem(IntToStr(i), nil); //until here the code works
   Inc(i, 1000);                         
  end;

你有什么建议吗?

【问题讨论】:

  • 虽然我和许多人都知道您遇到的错误类型的性质,但您应该始终告诉我们错误消息是什么。
  • 请完整阅读错误消息并查阅 (F1) 文档以解决问题。它说明了您不能修改 for 循环的计数器。

标签: delphi pascal


【解决方案1】:

@AndreasRejbrand 的解决方案的替代方案是 while 循环:

i := 40000;
while i <= 90000 do
begin
  ComboBox1.AddItem(IntToStr(i), nil);
  Inc(i, 1000);
end;

或“重复”:

i := 40000;
repeat
  ComboBox1.AddItem(IntToStr(i), nil);
  Inc(i, 1000);
until i > 90000;

【讨论】:

  • +1 但我认为使用&lt;= 90000 对某些人来说不会那么混乱。
  • @Jerry:我不建议改用它;我只是提供了一个替代方案。我赞成安德烈亚斯的回答。 :-)
  • 我的意思是我会使用&lt;= 90000 而不是&lt; 90001,它做同样的事情并且不一定重要,除了可读性之外
  • @Jerry:是的,你是对的。那将更具可读性。编辑修复。谢谢。
  • @No'am 可能是因为原发帖人使用了AddItem
【解决方案2】:

您不能在循环内更改 for 循环变量。

你想要的是这个:

for i := 0 to 50 do
  ComboBox1.AddItem(IntToStr(40000 + 1000 * i), nil)

但是!这是相当低效的。你应该考虑

ComboBox1.Items.BeginUpdate;
for i := 0 to 50 do
  ComboBox1.Items.Add(IntToStr(40000 + 1000 * i));
ComboBox1.Items.EndUpdate;

【讨论】:

  • 尽管这样可以完成工作,但我认为这种类型的循环为读者隐藏了逻辑。通常我尝试将此循环实现为@KenWhite 所示的while 循环,但更进一步的是实现一个库来处理for..step 循环。看我的回答,第二个将是我的公用事业的守护者。
  • @LURD:我正准备在我的答案中添加while 选项,但肯打败了我。无论如何,我认为这取决于“基础”逻辑。有时for 循环可能是最自然的循环。 (人们可能会觉得while 方法试图模拟程序员应该在设计时真正证明的东西。)
【解决方案3】:

编译器禁止更改循环变量。

有一种方法可以支持for..step 循环。 您必须拥有支持泛型 (Delphi-2009+) 的 Delphi 版本。

只需在实用程序单元中进行此声明:

Type
  ForLoop = record
    class procedure Step( Start,Stop,AStep : Integer; 
                          ALoop : TProc<Integer>); static;
  end;

class procedure ForLoop.Step(Start,Stop,AStep : Integer; ALoop: TProc<Integer>);
begin
  while (start <= stop) do
  begin
    ALoop(start);
    Inc(Start,AStep);
  end;
end;

并像这样使用它:

ForLoop.Step( 40000,90000,1000,
  procedure ( i : Integer)
  begin
    ComboBox1.AddItem(IntToStr(i), nil);
  end
);

在 Delphi-2005 中,添加了记录方法以及 for in 枚举。

知道了这一点,就可以实现另一个带有步进功能的 for 循环。

type
  Range = record
  private
    FCurrent,FStop,FStep : Integer;
  public
    constructor Step( Start,Stop,AnIncrement : Integer);
    function GetCurrent : integer; inline;
    function MoveNext : boolean; inline;
    function GetEnumerator : Range; // Return Self as enumerator
    property Current : integer read GetCurrent;
  end;

function Range.GetCurrent: integer;
begin
  Result := FCurrent;
end;

function Range.GetEnumerator: Range;
begin
  Result := Self;
end;

function Range.MoveNext: boolean;
begin
  Inc(FCurrent,FStep);
  Result := (FCurrent <= FStop);
end;

constructor Range.Step(Start,Stop,AnIncrement: Integer); 
begin
  Self.FCurrent := Start-AnIncrement;
  Self.FStop := Stop;
  Self.FStep := AnIncrement;
end;

现在你可以写了:

for i in Range.Step(40000,90000,1000) do
  ComboBox1.AddItem(IntToStr(i), nil);

要深入了解此示例的内部工作原理,请参阅 more-fun-with-enumerators。


上面两个示例的.StepReverse 版本很容易实现,我将把它作为练习留给感兴趣的读者。

【讨论】:

    【解决方案4】:

    我们也可以做一个从 40 到 90 的循环,并将索引乘以 1000

    var i: integer;
    begin
        for i:= 40 to 90 do
        begin
            ComboBox1.AddItem(IntToStr(i*1000), nil);     
        end;                 
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      相关资源
      最近更新 更多