第六章 循环控制
? 6,1 概 述
? 例如,要输入全校学生成绩;
求若干个数之和;
迭代求根、阶乘等。
? 循环结构是结构化程序三种基本结构之一,
它和顺序结构、选择结构共同作为各种复
杂程序的基本构造单元。
在 c语言中可以用以下语句来实现循环,
1,用 goto语句和 if语句构成循环;
2,用 while语句;
3,用 do一 while语句;
4,用 for语句;
6.2 goto语句以及用 goto语句构成循环
goto语句为无条件转向语句, 它的一般形式为,
goto 语句标号;
语句标号用标识符表示, 它的定名规则与变量名相
同, 即由字母, 数字和下划线组成, 其第一个字符必须为
字母或下划线 。 不能用整数来作标号 。 例如,
goto labeL1; ---合法
goto l23; --不合法
[例 6.1] 用 IF和 GOTO语句构成循环, 求和 (p106)
main()
{int i,sum=0;
i=1;
1oop,if( i<= 100)
{sum= sum十 i;
i++;
goto loop; }
printf(, % d”,sum) ; }
运行结果如下,5050
思考:关于 GOTO语句的用法的优缺点
图 6。 1
表达式
语句
0
非 0
6,3 while语句
, 当型, 循环结构 。
一般形式如下,
whi1e ( 表达式 ) 语句;
当表达式为非 0值时执行 while语句中
的内嵌语句。其流程图见图 6·1。其特
点是先判断表达式,后行语句 。
例 6,2 求 1+2+…+100的和 (p107)
i=1
i<=100
Sum=sum+i
i=i+1
0
非 0
图 6.2
main()
{int i,sum=0;i=1;
while (i<=100)
{sum=sum+i;i++;}
printf(“%d”,sum);}
关于循环体语句的思考,
( 1) 哪些语句需要循环, 即重复执行 。
( 2) 在循环体中应有使循环趋向结束的语句 。
表达式
语句
图 6。 3
非 0
0
6,4 do一 while语句
, 直到型, 循环结构 。
一般形式,do 语句
循环体
while ( 表达式 ) ;
其特点是,先执行语句, 后判断表达式 。
执行过程,先执行一次指定的内嵌的语句, 然
后判别表达式, 当表达式的值为非 0(, 真, )
时, 返回重新执行该语句, 如此反复, 直到表
达式的值等 0为止, 此时循环结束 。 ( 见图
6.3) 。
i<=100
i=1
sum=sum+I
I=I+1
图 6。 4
例 6,3 用 do-while语句
main()
{int i,sum=0;i=1;
Do
{sum=sum+i;i++;}
While(i<=100);
Printf(“%d”,sum);}
对同一个问题可以用 while语句处理, 也
可以用 do一 while语句处理 。 do一 while结
构可以转换成 while结构 。
比较以下程序的区别,
[ 例 6,4] while和 do一 while循环的比较 (p109)。
(1) main( ) ( 2) main( )
{ int sum= 0,i; {int sum=0,i;
scanf(, % d”,& i) ; scanf(, % d”,&i) ;
while( i<= 10) do
{sum=sum十 i; { sum= sum十 I;
i++; i++;
} } while(i<=10);
printf(“%d”,sum);} printf(“%d”,sum);}
6,5 for 语句
使用形式,for( 表达式 1;表达式 2;表达式 3) 语句
for (I=1;I<=100;I++) sum=sum+i
执行过程,
(1)先求解表达式 1;
(2)求解表达式 2,若其值为真 ( 非 0), 则执行
for语句中指定的内嵌语句, 然后执行下面第 ( 3) 步,
若为假 ( 0), 则结束循环, 转到第 ( 5) 步 。
(3)若表达式为真,在执行指定的语句后,求
解表达式 3。
(4) 转回上面第 ( 2) 步骤继续执行 。
(5) 执行 FOR语句下面的一个语句 。
表达式 1
语句
FOR下一语句
表达式 3
表达式 2 F
T
图 6.6
图 6,6表示 for语句的执行过程 。
for语句最简单的应用形式如下,
for( 循环变量赋初值;循环条件;循环
变量增值 ) 语句
它相当于,
i=1; while(i<=100) {sum=sum+i; i++;}
求解表达式 1
语句
求解表达式 3
图 6.7
以上 FOR语句的一般形式可以改写如下,
表达式 1;
while( 表达式 2)
{ 语句;表达式 3; }
注意,
1,for语句中表达式 1可以省略, 其后的分号不能省
略 。 执行时, 跳过, 求解表达式 1”这一步, 其它
不变 。
2,如果表达式 2省略, 即不判断循环条件, 循环无终
止地进行下去 。 此时循环体中应有跳出循环的语
句 。 图 6.7表示这种情况 。
例如,for ( i= l;; i++) sum= sum+i它相当于,
i= 1;
while( 1)
{sum= sum+i; i++; }
3,表达式 3也可以省略, 应另外设法保证循环能正常
结束 。 如,
for( sum= 0,i= 1; i<= 100; )
{ sum= sum十 1; i++;}
以上循环是否可以正常结束?
4,可以省略表达式 1和表达式 3,只有表达式 2,即只
给循环条件 。
for( ; i<= 100; ) {sum= sum+i; i++; }
?while ( I<=100) {sum= sum+ i; i++; }
5,三个表达式都可省略, 如
for ( ;; ) 语句
? while ( 1) 语句
6,表达式 1可以是设置循环变量初值的赋值表达式, 也
可以是与循环变量无关的其它表达式 。 如
for ( sum= 0,I=0; i<= 100; i++ ) sum= sum+ i;
表达式 3也类似 。 表达式 1和表达式 3可以是一个简单的表这式,
也可以是逗号表达式即包含一个以上的简单表达式, 中间用逗号间
隔 。
请判断以下程序中 sum和 K的结果是否相同,
for(sum=0,i=1;i<=100;i++) sum=sum+i;
for(i=0,j=100,k=0;i<=j;i++,j--) k=i+j ;
7.表达式 2一般是关系表达式或逻辑表达式, 但
也可以是数值表达式或字符表达式, 只要其值为非
零就执行循环体 。
例如,p112
for (;(c=getchar())!=?\n?;) printf(“%c”,c);
6,6循环的嵌套
一个循环体内又包含另一个完整的循环结构, 称为循环的嵌套 。
内嵌的循环中还可以嵌套,
三种循环 ( whi1e循环, do一 whi1e循环和 for循环 ) 可以互相嵌套 。
6,7几种循环的比较
p114
6.8 break语句和 continue语句
6.8.1 break语句
bleak语句可以从循环体内跳出循环体, 即提前
结束循环, 接着执行循环下面的语句 。 如
for( r=1; r<=10; r++)
{area=pi*r*r;
if (area>100) break;
printf(, %f”,area) ;}
计算 r= 1到 r= 10时的圆面积, 直到面积 area大于 100
注意, break语句不能用于循环语句和 switch语句之外
的任何其它语句中 。
6,8,2 continue语句
一般形式为 continue;
其作用为结束本次循环, 即跳过循环体中下面尚
未执行的语句, 接着进行下一次是否执行循环的
判定 。
continue语句和 break语句的区别是,continue语
句只结束本次循环, 而不是终止整个循环的执行,
而 break语句则是结束循环, 不再进行条件判断 。
[ 例 6.5] 把 100~ 200之间的不能被 3整除的数输出 。
main ()
{ int n;
for( n=100;n<= 200;n++ )
if(n%3==0) continue;
printf(, %d”,n);
}
例 6.6 (p116)
图 6.8
F1=1,f2=2
For I= 1 to 20
输出 f1,f2
f1=f1+f2
f2=f2+f1
[例 6,7] 求 Fibonacci数列,1,1,2,3,5,
8,……的前四十个数, 即
F1=1 (n=1)
F2=1 (n=2)
Fn=Fn-1+F n-2 (n>=3)
算法如图 6.8所示,程序如下,
main()
{ long int f1,f2;
int I; f1=1;f2=1;
for(I=1;I<=20)
{printf(“%12ld %12ld,,f1,f2);
if(I%2==0) printf(“\n”);
f1=f1+f2;f2=f2+f1;} }
读入 m
k=sqrt(m)
I=2
当 I<=k
m被 I整除
真 假
用 break结
束循环
I=I+1
I>=k+1
真 假
输出是素数 输出不是素数
图 6.14
[例 6.8] 判 m是否素数 。
算法如图 5,14所示 。
我们采用的算法是这样的:让 m被
2到 m的算术平方根 k(取整 )除, 如果 m
能被 2--k之中任何一个整数整除, 则
提前结束循环, 此时 i必然小于或等于
k;如果 m不能被 2~ k之间的任一整数
整除, 则在完成最后一次循环后, i还
要加 1,因此 i= k十 1,然后才终止循
环 。 在循环之后判别 i的值是否大子或
等于 k+ 1,若是则表明未曾彼 2~ k之
间任一整数整除过, 因此输出, 是素
数, 。
#include,math.h”
main()
{ int m,i,k;
scanf(, %d”,&m) ;
k= sqrt( m) ;
for( i=2;i<=k;i++)
if( m %I==0) break;
if( j>=K+1) printf(, %d is a prime number\
n”,m);
else printf(, %d is not a prime number\n”,m) ;
}
[例 6.9] 求 100~ 200间的全部素数 。
解题思路?
#inc1ude,math.h”
main ()
{int m,k,I,n=0;
for(m=101;m<= 200; m=m+2〕
{if(n% 10==0) printf(, \n”) ;
k=sqrt(m);
for (i= 2;I<=k;i++)
if( m%I==0) break;
if (I>= k+ 1) {printf
(, %d”,m) ;n=n+l;} } }
[例 6.10] 译密码 。 将每个英文字母循环变为其
后的第四个字母 。 将字母 A变成字母 E,a变成 e,
w变成 a,W变成 A,z变成 d,Z变成 D,非字母字符
不变 。 输入一行字符, 要求输出其相应的密码 。
程序如下,
#include,stdio.h”
main()
{char c;
while(c=getchar()!=’\n’)
{if((c>=’a’&&c<=’z’)||(c>=’A’&& c<=’Z’))
c=c+4;
if (c>=’Z’ &&c<=’Z’+4)||(c>’z’) c=c-26;}
printf(“%c”,c);
} }
运行结果如下,
China!
Glmre!
本章作业
? 6,1 概 述
? 例如,要输入全校学生成绩;
求若干个数之和;
迭代求根、阶乘等。
? 循环结构是结构化程序三种基本结构之一,
它和顺序结构、选择结构共同作为各种复
杂程序的基本构造单元。
在 c语言中可以用以下语句来实现循环,
1,用 goto语句和 if语句构成循环;
2,用 while语句;
3,用 do一 while语句;
4,用 for语句;
6.2 goto语句以及用 goto语句构成循环
goto语句为无条件转向语句, 它的一般形式为,
goto 语句标号;
语句标号用标识符表示, 它的定名规则与变量名相
同, 即由字母, 数字和下划线组成, 其第一个字符必须为
字母或下划线 。 不能用整数来作标号 。 例如,
goto labeL1; ---合法
goto l23; --不合法
[例 6.1] 用 IF和 GOTO语句构成循环, 求和 (p106)
main()
{int i,sum=0;
i=1;
1oop,if( i<= 100)
{sum= sum十 i;
i++;
goto loop; }
printf(, % d”,sum) ; }
运行结果如下,5050
思考:关于 GOTO语句的用法的优缺点
图 6。 1
表达式
语句
0
非 0
6,3 while语句
, 当型, 循环结构 。
一般形式如下,
whi1e ( 表达式 ) 语句;
当表达式为非 0值时执行 while语句中
的内嵌语句。其流程图见图 6·1。其特
点是先判断表达式,后行语句 。
例 6,2 求 1+2+…+100的和 (p107)
i=1
i<=100
Sum=sum+i
i=i+1
0
非 0
图 6.2
main()
{int i,sum=0;i=1;
while (i<=100)
{sum=sum+i;i++;}
printf(“%d”,sum);}
关于循环体语句的思考,
( 1) 哪些语句需要循环, 即重复执行 。
( 2) 在循环体中应有使循环趋向结束的语句 。
表达式
语句
图 6。 3
非 0
0
6,4 do一 while语句
, 直到型, 循环结构 。
一般形式,do 语句
循环体
while ( 表达式 ) ;
其特点是,先执行语句, 后判断表达式 。
执行过程,先执行一次指定的内嵌的语句, 然
后判别表达式, 当表达式的值为非 0(, 真, )
时, 返回重新执行该语句, 如此反复, 直到表
达式的值等 0为止, 此时循环结束 。 ( 见图
6.3) 。
i<=100
i=1
sum=sum+I
I=I+1
图 6。 4
例 6,3 用 do-while语句
main()
{int i,sum=0;i=1;
Do
{sum=sum+i;i++;}
While(i<=100);
Printf(“%d”,sum);}
对同一个问题可以用 while语句处理, 也
可以用 do一 while语句处理 。 do一 while结
构可以转换成 while结构 。
比较以下程序的区别,
[ 例 6,4] while和 do一 while循环的比较 (p109)。
(1) main( ) ( 2) main( )
{ int sum= 0,i; {int sum=0,i;
scanf(, % d”,& i) ; scanf(, % d”,&i) ;
while( i<= 10) do
{sum=sum十 i; { sum= sum十 I;
i++; i++;
} } while(i<=10);
printf(“%d”,sum);} printf(“%d”,sum);}
6,5 for 语句
使用形式,for( 表达式 1;表达式 2;表达式 3) 语句
for (I=1;I<=100;I++) sum=sum+i
执行过程,
(1)先求解表达式 1;
(2)求解表达式 2,若其值为真 ( 非 0), 则执行
for语句中指定的内嵌语句, 然后执行下面第 ( 3) 步,
若为假 ( 0), 则结束循环, 转到第 ( 5) 步 。
(3)若表达式为真,在执行指定的语句后,求
解表达式 3。
(4) 转回上面第 ( 2) 步骤继续执行 。
(5) 执行 FOR语句下面的一个语句 。
表达式 1
语句
FOR下一语句
表达式 3
表达式 2 F
T
图 6.6
图 6,6表示 for语句的执行过程 。
for语句最简单的应用形式如下,
for( 循环变量赋初值;循环条件;循环
变量增值 ) 语句
它相当于,
i=1; while(i<=100) {sum=sum+i; i++;}
求解表达式 1
语句
求解表达式 3
图 6.7
以上 FOR语句的一般形式可以改写如下,
表达式 1;
while( 表达式 2)
{ 语句;表达式 3; }
注意,
1,for语句中表达式 1可以省略, 其后的分号不能省
略 。 执行时, 跳过, 求解表达式 1”这一步, 其它
不变 。
2,如果表达式 2省略, 即不判断循环条件, 循环无终
止地进行下去 。 此时循环体中应有跳出循环的语
句 。 图 6.7表示这种情况 。
例如,for ( i= l;; i++) sum= sum+i它相当于,
i= 1;
while( 1)
{sum= sum+i; i++; }
3,表达式 3也可以省略, 应另外设法保证循环能正常
结束 。 如,
for( sum= 0,i= 1; i<= 100; )
{ sum= sum十 1; i++;}
以上循环是否可以正常结束?
4,可以省略表达式 1和表达式 3,只有表达式 2,即只
给循环条件 。
for( ; i<= 100; ) {sum= sum+i; i++; }
?while ( I<=100) {sum= sum+ i; i++; }
5,三个表达式都可省略, 如
for ( ;; ) 语句
? while ( 1) 语句
6,表达式 1可以是设置循环变量初值的赋值表达式, 也
可以是与循环变量无关的其它表达式 。 如
for ( sum= 0,I=0; i<= 100; i++ ) sum= sum+ i;
表达式 3也类似 。 表达式 1和表达式 3可以是一个简单的表这式,
也可以是逗号表达式即包含一个以上的简单表达式, 中间用逗号间
隔 。
请判断以下程序中 sum和 K的结果是否相同,
for(sum=0,i=1;i<=100;i++) sum=sum+i;
for(i=0,j=100,k=0;i<=j;i++,j--) k=i+j ;
7.表达式 2一般是关系表达式或逻辑表达式, 但
也可以是数值表达式或字符表达式, 只要其值为非
零就执行循环体 。
例如,p112
for (;(c=getchar())!=?\n?;) printf(“%c”,c);
6,6循环的嵌套
一个循环体内又包含另一个完整的循环结构, 称为循环的嵌套 。
内嵌的循环中还可以嵌套,
三种循环 ( whi1e循环, do一 whi1e循环和 for循环 ) 可以互相嵌套 。
6,7几种循环的比较
p114
6.8 break语句和 continue语句
6.8.1 break语句
bleak语句可以从循环体内跳出循环体, 即提前
结束循环, 接着执行循环下面的语句 。 如
for( r=1; r<=10; r++)
{area=pi*r*r;
if (area>100) break;
printf(, %f”,area) ;}
计算 r= 1到 r= 10时的圆面积, 直到面积 area大于 100
注意, break语句不能用于循环语句和 switch语句之外
的任何其它语句中 。
6,8,2 continue语句
一般形式为 continue;
其作用为结束本次循环, 即跳过循环体中下面尚
未执行的语句, 接着进行下一次是否执行循环的
判定 。
continue语句和 break语句的区别是,continue语
句只结束本次循环, 而不是终止整个循环的执行,
而 break语句则是结束循环, 不再进行条件判断 。
[ 例 6.5] 把 100~ 200之间的不能被 3整除的数输出 。
main ()
{ int n;
for( n=100;n<= 200;n++ )
if(n%3==0) continue;
printf(, %d”,n);
}
例 6.6 (p116)
图 6.8
F1=1,f2=2
For I= 1 to 20
输出 f1,f2
f1=f1+f2
f2=f2+f1
[例 6,7] 求 Fibonacci数列,1,1,2,3,5,
8,……的前四十个数, 即
F1=1 (n=1)
F2=1 (n=2)
Fn=Fn-1+F n-2 (n>=3)
算法如图 6.8所示,程序如下,
main()
{ long int f1,f2;
int I; f1=1;f2=1;
for(I=1;I<=20)
{printf(“%12ld %12ld,,f1,f2);
if(I%2==0) printf(“\n”);
f1=f1+f2;f2=f2+f1;} }
读入 m
k=sqrt(m)
I=2
当 I<=k
m被 I整除
真 假
用 break结
束循环
I=I+1
I>=k+1
真 假
输出是素数 输出不是素数
图 6.14
[例 6.8] 判 m是否素数 。
算法如图 5,14所示 。
我们采用的算法是这样的:让 m被
2到 m的算术平方根 k(取整 )除, 如果 m
能被 2--k之中任何一个整数整除, 则
提前结束循环, 此时 i必然小于或等于
k;如果 m不能被 2~ k之间的任一整数
整除, 则在完成最后一次循环后, i还
要加 1,因此 i= k十 1,然后才终止循
环 。 在循环之后判别 i的值是否大子或
等于 k+ 1,若是则表明未曾彼 2~ k之
间任一整数整除过, 因此输出, 是素
数, 。
#include,math.h”
main()
{ int m,i,k;
scanf(, %d”,&m) ;
k= sqrt( m) ;
for( i=2;i<=k;i++)
if( m %I==0) break;
if( j>=K+1) printf(, %d is a prime number\
n”,m);
else printf(, %d is not a prime number\n”,m) ;
}
[例 6.9] 求 100~ 200间的全部素数 。
解题思路?
#inc1ude,math.h”
main ()
{int m,k,I,n=0;
for(m=101;m<= 200; m=m+2〕
{if(n% 10==0) printf(, \n”) ;
k=sqrt(m);
for (i= 2;I<=k;i++)
if( m%I==0) break;
if (I>= k+ 1) {printf
(, %d”,m) ;n=n+l;} } }
[例 6.10] 译密码 。 将每个英文字母循环变为其
后的第四个字母 。 将字母 A变成字母 E,a变成 e,
w变成 a,W变成 A,z变成 d,Z变成 D,非字母字符
不变 。 输入一行字符, 要求输出其相应的密码 。
程序如下,
#include,stdio.h”
main()
{char c;
while(c=getchar()!=’\n’)
{if((c>=’a’&&c<=’z’)||(c>=’A’&& c<=’Z’))
c=c+4;
if (c>=’Z’ &&c<=’Z’+4)||(c>’z’) c=c-26;}
printf(“%c”,c);
} }
运行结果如下,
China!
Glmre!
本章作业