基本语句(三)
§5.1 FOR语句
FOR语句用于循环次数已知的情况,有两种形式:
FOR <控制变量> := <初值> TO <终值> DO <语句>; FOR <控制变量> := <初值> DOWNTO <终值> DO <语句>; FOR语句的两种形式的逻辑功能图: 控制变量:=初值 控制变量:=初值 false false 变量<=终值 变量>=终值 true true 循环体 循环体
控制变量=初值+1 控制变量=初值-1 下一条语句 下一条语句
(a)TO情况 (a)DOWNTO情况
控制变量控制重复的次数,它从初值到终值自动顺序取值(分递增和递减两种顺序),每取一次值就执行一次循环体,直到控制变量的值大于(对于for-to-do)或小于(对于for-downto-to)终值。
【例】计算1+2+3+4+……+100之和。
分析:设变量s为累加和,初值为0,然后依次加上1,2,3,……,一直到100; 输出s的值。 算法: ① s := 0;
② s := s+1; s := s+2; ……
s := s+100; ③ 输出s
步骤②中,要重复写上100个赋值语句,其变化只是加号后的数值。因此,我们可以用一个for语句来代替这100个语句: ② for i := 1 to 100 do program sample3611; s := s + i ;
var i , s :integer; 程序:
begin
s := 0; {s置初值0}
for i := 1 to 100 do s := s + i ; 25 writeln(’s=’,s); {输出累加和s} end.
s为累加和,初值为0;
1 i为控制变量,初值为1,终值为100; 第一次执行循环体时,i的值为1,
1+0 s := s + i → s := 0 + 1 , 执行后s=1;
1 0 i s
3 第二次执行循环体时,i的值变为2,
s := s + i → s := 1 + 2 , 执行后s=3;
2+1
2 1
i s 第三次执行循环体时,i的值变为3,
s := s + i → s := 3 + 3 , 执行后s=6; 第四次 …… ……
【例】 读入n个数,计算它们的和与积以及平均值。
分析: 读入n ,n为整型变量; 设每次读入的数放置在变量x中,和、积以及平均值分别用sum,mul,ave存放,它们都为实型变量。
为了求sum,mul与ave,可以利用一个循环,让它循环n次,每循环一次,读一个新的x值,并把它分别加到sum上,乘到mul上。 注意,在循环前应将sum置为0,将mul置为1。
循环结束后,将sum除以n,求出ave,最后输出sum,mul,ave。 算法: ①读入n; 置sum初值为0 , mul为1; ② for j := 1 to n do 1. 读入x
2. 将x累加到sum上: sum := sum + x ; 3. 将x累乘到mul上: mul := mul + x ; ③ 计算ave: ave := sum / n ; ④ 输出sum,mul,ave
程序: program sample3612;
var x , sum , mul , ave :real ; {sum为和、mul为积、ave为平均值} j , n:integer ; Begin
readln(n); {读入n}
26
sum := 0; mul := 1; {sum、mul置初值}
for j := 1 to n do {循环n次,j为控制变量}
begin {循环体内的语句不止一句,所以要用begin和end括起} read(x); {每次读入新的x} sum := sum + x; {将x累加到sum上} mul := mul * x; {将x累乘到mul上} end;
ave := sum / n; {求平均值ave}
writeln(’sum=’ , sum , ’ mul=’, mul , ’ ave=’, ave); End.
累加求和之前,累加单元(如sum)一定要清0,否则它可能是一个任意数,这样在第一次累加时就不对了。同理,在累乘求积前,累乘单元(如mul)必须置初值1,否则会出错。
清0和置1,一定要在循环前做,在循环中执行累加和累乘。(思考:否则会怎样?)
循环体中如果有多个语句,必须用begin和end括起作为一个语句(复合语句)。 【注意】
1. 初值和终值可以是表达式。控制变量的类型必须与初值、终值的类型相同。 控制变量必须是有序类型,常用整型、字符型,不允许为实型变量。
2. FOR语句的步长是一定的,虽Pascal允许在循环体内修改控制变量,但一般不赞成这样做,在循环体中改变控制变量往往会造成混乱。 如: for k := 1 to 100 do begin
k := 3; {循环体中改变了循环变量k的值} ……
end.
3. 当FOR语句执行完毕后,控制变量的值无定义,因此FOR语句的后续语句不能认为控制...变量的值是终值而加以利用。
4. 当初值超过终值时,不执行循环,循环次数为0。
如: for aa := 10 to 1 do …… {将不执行循环}
§5.1 FOR语句的嵌套
在实际应用中,可能在循环体内再包含有重复语句,这就出现了嵌套问题。以上三种循环语句都允许自己之间或相互之间嵌套,这样一层套一层便形成了多重循环。 下面是一个二重循环语句: for i := 1 to 3 do for j := 1 to 4 do begin 外层内层
27
k := i * j;
writeln(’i=’, i ,’ j=’, j , ’ k=’, k); end;
可见,内层的重复语句是包含它的外层重复语句的一个循环体。 使用多重循环时,必须注意:内层循环必须完全被包含在外层循环体内,内外循环不得循环..................骑跨,对嵌套的FOR语句而言,内外层循环的控制变量不能同名。下面的两段程序都是不允...................许的:
for i := 1 to 10 do for i := 1 to n do begin begin repeat ……
x := x + 1; for i := 1 to n do write(x); …… end; end; until x > 100;
【例】打印九九乘法表,大家注意观察循环的嵌套。
program s99;
var i, j : integer;
begin
for i:=1 to 9 do begin {循环体内的语句不止一句,所以要用begin和end括起}
for j:=1 to i do write (j , ’*’ , i , ’=’ , i*j , ’ ’);
writeln; {输出换行}
end; 变量变化情况及输出: end. i=1 j=1 1*1=1 换行 输出: i=2 j=1 1*2=2 1*1=1 j=2 2*2=4 换行 1*2=2 2*2=4 i=3 j=1 1*3=3 1*3=3 2*3=6 3*3=9 j=2 2*3=6 j=3 3*3=9 换行 …… …… 【例】把一张一元钞票换成一分、二分和五分的硬币(每种至少一枚),问有哪几种换法? 分析: 这道题是一个组合问题,采用穷举法解决: 令五分钱硬币的个数为k,k的取值范围为1~19 ; 二分钱硬币的个数为j,j的取值范围为1~49 ; 一分钱硬币的个数则为100-k×5-j×2 ; n为计数器,累计兑换方案的总数。
这样利用二重循环就可以得到每一种组合。 程序:
program s100; var i , j , k , n : integer;
begin n := 0; { 计数器n清0 } for k := 1 to 19 do { 五分硬币的个数 } 28
【例】输出如下图形,行数n由键盘输入。
*
***
n行
*****
………
1
分析:如果觉得输出这个图形有困难的话,我们先做个最简单的:
2
读入 n ,输出n行,第1行输出1,第2行输出2,…… 3
n行 这个程序很容易实现: …
n
program x01;
var n , i :integer;
begin
readln(n); for i:=1 to n do {循环控制变量i可以利用} writeln ( i ); {第i行输出的数字是i } end.
接着,我们试着来输出这样的图形: * **
n行
观察这个图形,可以发现,第i行上正好有i个 ’ * ’,我*** 们可以利用二重循环,外循环控制行数,控制变量i表示正在………输出第i行;内循环控制输出 ’ * ’,控制变量j表示输出j个’ * ’。
program x02; var n , i , j :integer; begin readln(n); for i:=1 to n do begin {为什么要加begin}
for j:=1 to i do write (’ * ’); {这里改成writeln行不?为什么?} writeln; {这句删去会出现什么情况?} 29 end; end.