1.While 循环
While 语句的语法格式为: While 条件表达式 do
循环语句; 循环语句可以是任何合法的语句,也可以是另一个循环语句。条件表达式返回一个逻辑
类型的值,当其为 True 时,系统执行其后的循环语句,每执行完一次循环语句时系统均会
判断条件表达式的值,若为 True 则断续执行,若为 False 则终止执行当前的 while 循环而 执行 while 循环后的语句。
以下程序将计算 1+2+3+„+N 的和,N 的值由用户指定(为降低复杂性,N 值不可大于 100):
program SumInt;
{$APPTYPE CONSOLE}
uses
- 64 -
SysUtils;
var
n,i:1..100;
Sum:integer; begin
write('请输入一个 1 至 100 间的数字:');
read(n);
sum := 0; //将 sum 的值初始化为 0 I := 1;
while i < = n do //当 i 的值小于 n 时执行循环体 begin
sum := sum+i;
i := i+1; //每执行完一次,i 的值增加 1 end;
writeln(inttostr(sum)); //显示 sum 的值 readln;
End.
注意例子中的 i := i+1,若没有这句代码,i 的值永远为 1,程序将会一直执行循环至 死机,即陷入死循环。
将 while 中的条件表达式省略时,也会致使此循环永不停止,这样的循环称之为空 循环。
Repeat 循环与 while 循环非常类似,唯一的区别在于:while 循环第一次时先判断 条件是否满足之后再执行循环休,而 repeat 循环第一次执行时先执行循环休再判断条件。
Repeat 语句的语法格式为: Repeat
[循环体]
Until <条件表达式>
将前面的 SumInt 改写成 repeat 循环,其代码为: begin
write('请输入一个 1 至 100 间的数字:'); read(n);
sum := 1; //将 sum 的值初始化为 1 i := 1;
repeat
i := i+1;
sum := sum+i; //这两句语句的顺序不可调换 until i = n;
writeln(inttostr(sum)); //显示 sum 的值 read(i);
End.
- 65 -
以下两个问题请读者自行思考:
l 为何 sum 的初始值由 0 变成了 1?
l Repeat 循环体中的两句语句的顺序能否调换?
当我们知道将要循环的次数时,可用 for 循环。其语法格式为; For 计数器 := 初值 to 终值 do
< 循环体 > 说明:
1.计数器必须为有序类型的变量,初值与终值必须为有序类型的常量或变量
2.计数器、初值、终值的数据类型必须相互兼容,最好全部相同
执行 For 语句时,系统先将初值赋予计数器(故而计数器不需要预先手动赋予初始 值),然后判断计数器与终值的关系,若计数器小于或等于终值,系统将执行一次循环,并
将计数器的值加 1。当计数的值大于终值时,系统将停止循环,此时计数器的值等于终值 加 1。当初值大于终值时不会发生循环。
For 语句还有另一种形式的格式: For 计数器 := 初值 downto 终值 do
<循环体>
此种形式与前一种形式相反,系统每次执行完循环后,会将计数器的值减 1,直到计数 器的小于终值为止。此种形式的 for 语句执行完毕后计数器值比终值小 1。显然,初值小 于终值时将不会发生循环。
注意:对于任何形式的 for 语句而言,当初值与终值相等时,系统只执行一次循 环。如下面的例子:
program ForSample;
{$APPTYPE CONSOLE}
uses
SysUtils; var
I,n:integer;
Begin
write('输入 n 的值:'); read(n);
for i := 1 to n do
writeln('Delphi2010'); //系统执行 n 次循环 writeln('i 的值为:'+inttostr(i)); //显示此时 i 的值
read(n); End.
上面的程序要求用户输入一个数字作为 n 的值,然后在屏幕上显示 n 行文字,当
for 执行完毕后 i 的值为 n+1。
当 n 的值为 1 时,只显示一行文字,且 for 语句执行完毕后 i 的值为 2。 注意,本例中 for 循环中的初值为 1,所以执行 n 次循环。当将初值改为其它值
- 66 -
Var
请读者思考一下,对于如下集合变量:
Myset:set of AnsiChar; Begin
Myset := ['A','B','C','D'];
End. 若现要求将其中的所有成员逐一在屏幕上显示出来,读者会怎么做? 可能读者会想到利用索引:
Var
Myset:set of AnsiChar; I:integer;
Begin
Myset := ['A','B','C','D'];
For i := 1 to 4 do Writeln(myset[i]);
End.
看起来很完美,但如果读者的记忆力还不错的话,就应该知道集合类型是不支持索引 的。所以以上代码无法通过编译。这咱时候我们可以使用 For...in 循环语句。
For...in 循环是 Delphi 新版本中新加入的一种循环语句,习惯上称为遍历语句,关 于其作用,笔者在此暂不介绍,若读者看完下面的例子后还不明白,那我说了也是白说。 遍历语句的语法格式为:
For V in set do <循环体> V 为任一合法变量。Set 为集合变量。V 与 set 的基本类型必须一致,至少相互兼容。 For...in 循环过程如下:先将集合中的第 1 个成员赋予变量 V 并执行循环体中的语 句,然后将第 2 个成员赋予 V 并执行循环体中的语句„依次类推,直到最后一个成员,此 过程称之为集合的遍历。注意:集合成员具有无序性,故系统执行时将根据赋值时各成员
出现的先后顺序来运行。如下面的例子: program ForSample;
{$APPTYPE CONSOLE}
uses
SysUtils;
Var
Myset:set of AnsiChar; ch:AnsiChar;
Begin
Myset := ['D','B','C','A'];
- 67 -
for ch in myset do Write(ch);
readln; End.
执行以上代码,屏幕显示:DBCA。
除 Set 类型外,for...in 还能遍历以下类型:
l 数组。一维二维多维均可,动态静态都行。遍历时将按序号由小到大进行遍历。
l 字符串。按照前后顺序从第一个字符开始遍历。
l 类、接口、记录。对于这三种类型的变量,实现遍历功能的过程较为复杂,一般很少 使用,在此我们不再介绍。Delphi 预先提供了以下几个类用以支持对象的遍历: Classes.TList
Classes.TCollection Classes.TStrings Classes.TInterfaceList Classes.TComponent Menus.TMenuItem ActnList.TCustomActionList DB.TFields ComCtrls.TListItems ComCtrls.TTreeNodes ComCtrls.TToolBar
下面以 Classes.TStrings 给出一个相关的示例:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
var
StrArray:TStringList; Item:String;
begin
StrArray := TStringList.Create; StrArray.Add('stringA'); StrArray.Add('stringB'); StrArray.Add('stringC');
for Item in StrArray do writeln(Item);
Readln; end.
运行这个程序,屏幕上显示以下 5 条字符串:
stringA stringB stringC
- 68 -
可能读者会奇怪,这个例子中使用的类是 TStringList 而非 TStrings,为何?我们知 道,类具有功能,TStrings 中的成员能够被遍历,也就意味着其所有的子类也可被遍历, 而 TStringList 正是 TStrings 的子类。但在这个例子中我们不使用 TStrings 的原因并不 仅限于此,还有另一个重要原因是:TStrings 是个抽象类,其中仅仅只是声明了相关的方 法而并未具体这些功能,所以无法用于遍历。
以上例子同时也说明:对于任何一个类,只要这个类的某个祖先类支持遍历,这个类 就可以被遍历。
continue 与 break 虽非循环语句,但此二者只用于前面介绍的四种循环语句,故在此 一并介绍。continue 用于跳出当前正在执行的一次循环并重新开始新一次的循环。Break 用于停止循环而执行循环语句后面的代码。
下面我们将通过一个例子说明一下此二者在 for...in 循环中的使用,当用于其它循环 语句时作用与 for...in 中一样。
program BreakSample;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
ch:char; str:string;
begin
str := 'ABCDEFGHIJKLMN';
for ch in str do begin
if ch = 'H' then break;
writeln(ch); end;
readln; End.
此程序遍历字符串 str 并显示其中的字符,但在循环体中设置了一条件:当遇到字符
串中的'H'时停止遍历,直接执行循环语句后面的代码即'readln;'。故而屏幕上只显示 'ABCDEFG'。
若将代码中的 break 改为 continue,循环体的条件则变为:当遇到'H'时不再断续执
行此次循环而会重新开始一次新的循环,所以屏幕上不会显示'H',只显示 'ABCDEFGIJKLMN'。