Originale-mail to me for new edition

 

For statements

 

A for statement, unlike a repeat or while statement, requires you to specify explicitly the number of iterations you want the loop to go through. The syntax of a for statement is

for counter := initialValue to finalValue do statement

or

for counter := initialValue downto finalValue do statement

where

·  counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.

·  initialValue and finalValue are expressions that are assignment-compatible with counter.

·  statement is a simple or structured statement that does not change the value of counter.

The for statement assigns the value of initialValue to counter, then executes statement repeatedly, incrementing or decrementing counter after each iteration. (The for...to syntax increments counter, while the for...downto syntax decrements it.) When counter returns the same value as finalValue, statement is executed once more and the for statement terminates. In other words, statement is executed once for every value in the range from initialValue to finalValue. If initialValue is equal to finalValue, statement is executed exactly once. If initialValue is greater than finalValue in a for...to statement, or less than finalValue in a for...downto statement, then statement is never executed. After the for statement terminates, the value of counter is undefined.

For purposes of controlling execution of the loop, the expressions initialValue and finalValue are evaluated only once, before the loop begins. Hence the for...to statement is almost, but not quite, equivalent to this while construction:

 

begin

  counter := initialValue;

  while counter <= finalValue do

  begin

    statement;

    counter := Succ(counter);

  end;

end

 

The difference between this construction and the for...to statement is that the while loop re-evaluates finalValue before each iteration. This can result in noticeably slower performance if finalValue is a complex expression, and it also means that changes to the value of finalValue within statement can affect execution of the loop.

Examples of for statements:

for I := 2 to 63 do

  if Data[I] > Max then

    Max := Data[I];

for I := ListBox1.Items.Count - 1 downto 0 do

  ListBox1.Items[I] := UpperCase(ListBox1.Items[I]);

for I := 1 to 10 do

  for J := 1 to 10 do

  begin

    X := 0;

    for K := 1 to 10 do

      X := X + Mat1[I, K] * Mat2[K, J];

    Mat[I, J] := X;

  end;

for C := Red to Blue do Check(C);

 

Topic groups

 

See also

Control loops

Repeat statements

Structured Statements: Overview

While statements

 

 

译文

 

For语句

 

repeatwhile语句不同,for语句需要明确指定循环次数。for语句的语法是:

for counter := initialValue to finalValue do statement

或者

for counter := initialValue downto finalValue do statement

这里,

·  计数器counter是一个局部序数型变量(声明在包含当前for语句的块中),并且不能含有任何限定词。

·  初始值initialValue和结束值finalValue是与计数器counter赋值兼容的表达式。

·  语句statement是简单语句或结构语句,但在语句中不能改变计数器counter的值。

for语句将初始值initialValue的值赋给计数器counter,然后重复执行语句statement,在每次循环之后递增或递减计数器counter的值。(在for...to语句中递增计数器counter的值,在for...downto语句中递减计数器counter的值。)当计数器counter返回的值与结束值finalValue的值相等时,语句statement再被执行一次,for语句终止。换句话说,语句statement将为初始值initialValue到结束值finalValue之间的每个值执行一次。如果initialValue等于finalValue,那么语句statement正好被执行一次。如果在for...to语句中的初始值initialValue大于结束值finalValue,或者在for...downto语句中的初始值initialValue小于结束值finalValue,那么语句statement不会被执行(相当于for语句什么也不做)。for语句终止后,计数器counter的值是不明确的。(因此,不能在for语句之后的语句中立即将计数器counter的值视为finalValue来使用。)

为控制循环的执行,表达式initialValuefinalValue在循环开始之前只被求值一次。因此,for...to语句几乎(但不完全)等价于下面的while语句:

 

begin

  counter := initialValue;

  while counter <= finalValue do

  begin

    statement;

    counter := Succ(counter);

  end;

end

 

上面的while语句与相应for...to语句之间的差别在于,while循环在每次重复之前都对finalValue进行了重新求值。这对于finalValue是一个混合表达式的情况来说,显然降低了执行效率;另外,在语句statement中改变finalValue的值也会影响循环的执行。

 

下面是for语句的一些例子:

 

for I := 2 to 63 do

  if Data[I] > Max then

    Max := Data[I];

 

for I := ListBox1.Items.Count - 1 downto 0 do

  ListBox1.Items[I] := UpperCase(ListBox1.Items[I]);

 

for I := 1 to 10 do

  for J := 1 to 10 do

  begin

    X := 0;

    for K := 1 to 10 do

      X := X + Mat1[I, K] * Mat2[K, J];

    Mat[I, J] := X;

  end;

 

for C := Red to Blue do Check(C);

 

主题组

 

相关主题

控制循环

Repeat语句

结构语句:概述

While语句

 

 

编者注

 

什么时候需要使用for...downto语句

for...to语句中,当一次反复可能会影响到下一次反复时,需要使用for...downto来替换。例如

for I := 0 to StringList.Count – 1 do begin

  if StringList.Strings[I] = 'To Delete' then

    StringList.Delete(I);

end;

这里的for...to语句希望执行这样一个程序逻辑:遍历StringList,删除所有串值为 'To Delete' 的项。这里的语法是完全正确的,编译器也不会报告任何提示和警告。但在执行中就有可能发生异常。这是因为,在每次检查到串值 'To Delete' 并对其删除之后,StringList中的项数就会相应递减,那么,对于每次删除,下一次循环实质上是跳过了一项(被跳过的项代替了被删除项的位置索引),这已经有违初衷了。此外,假定已经删除N(显然N应当小于或等于StringList.Count)项,那么在检查第(StringList.Count – N)项时,将会发生运行时错误,因为这时已经索引不到该项了。

 

为了详细说明,可以假设StringList中只有四项('Hello', 'To Delete', 'World', 'OK')。

第一次循环(I = 0)执行后,StringList没有变化;

第二次循环(I = 1)执行后,串 'To Delete' 被删除,StirngList变成('Hello', 'World', 'OK');

第三次循环(I = 2)中,if语句判定的是串 'OK' 而跳过了串 'World' (串 'World' 此时的索引是 1 而不是最初的 2);

第四次循环(I = 3)中,if语句将试图对表达式 StringList.String[3] = 'To Delete' 进行求值,这时将会引发异常,导致运行时错误,因为此时StringList有效索引范围是 [0..2] (只有3项)。

 

因此,对于此类程序逻辑,需要使用for...downto语句。上面的程序逻辑可以写成:

for I := StringList.Count – 1 downto 0 do begin

  if StringList.Strings[I] = 'To Delete' then

    StringList.Delete(I);

end;

这样,既不会跳过或漏掉任何一项,也不会引发异常。