Pascal:从长度中减去1以获得正确的大小

时间:2013-04-13 20:22:57

标签: for-loop pascal

我有一段这样的代码:

for I := 0 to Self.EventQueue.Count do
    Dispose(Self.EventQueue[I]);

当Count为0时,它会发出错误,因为它会尝试Dispose一个不存在的元素。当我将其更改为

for I := 0 to Self.EventQueue.Count-1 do
    Dispose(Self.EventQueue[I]);

一切正常。是否有任何优雅的方式来解决这个问题,还是这种常见做法?

3 个答案:

答案 0 :(得分:0)

OMG。那是因为在循环中从0到Self.EventQueue.Count,你遍历Self.EventQueue.Count + 1项。

答案 1 :(得分:0)

这是绝对正常的行为,并且在Delphi / FreePascal中的每个列表和容器类的帮助中都有记录。原因很清楚 - 如果列表中有三个项目,并且第一个项目位于索引0,那么您有0, 1, 2项,但Count3 ,对吗?

for i := 0 to StringList.Count - 1 do  // TStringList

for i := 0 to List.Count - 1 do        // TList

for i := 0 to StringGrid1.ColCount do  // TStringGrid

另一种选择并不那么明确(对我来说输入更糟糕):

for i := 0 to Pred(StringList.Count) do  

动态数组也从索引0开始。

var
  IntArray: array of Integer;
  i: Integer;
begin
  SetLength(IntArray, 10);
  for i := Low(IntArray) to High(IntArray) do  // loop is 0..9
    //
end;

FPC / Delphi中唯一不是0的东西是从1开始的字符串类型和非动态数组(在代码中声明为固定大小的数组) ,几乎可以从你想要的任何索引开始。例如,这是完全合法的:

var
  IntArray: array[-10..10] of Integer;
  i: Integer;
begin
  for i := Low(IntArray) to High(IntArray) do // loop is -10..10
    //
end;

除此之外,无论何时你在循环中做任何会减少列表中项目数量的事情,你都应该向后迭代:

for i := List.Count - 1 downto 0 do

否则,您将迭代超出列表的末尾,因为Count仅在循环开始时进行评估。

答案 2 :(得分:0)

我更喜欢使用

for I := 1 to Self.EventQueue.Count do
  Dispose(Self.EventQueue[I-1]);

很明显,如果计数为零并且指数的修正发生在重要的地方,则没有任何反应