第 5章 循环结构程序设计
? 循环语句
? break 和 continue 语句
? 循环嵌套
5.1 循环语句
? 问题
? 打印整数 1~ 10
? 打印整数 1~ 100
? 打印整数 1~ n
printf("%d",1);
printf("%d",2);
……
printf("%d",10);
i=1;
printf("%d",i); i++;
printf("%d",i); i++;
……
printf("%d",i); i++;
i=1;
while(i<=10){
printf("%d",i);
i++;
}
while 语句
while (表达式 )
语句;
语 句
表达式
非 0
0
i=1;
while(i<=10){
printf("%d",i);
i++;
}
循环条件
循环体
循环不变式
改变循环条件
10
求 sum= ? i
i=1
sum=0
sum+1 —> sum
sum+2 —> sum
sum+3 —> sum
……
sum+10 —> sum
sum=sum+?
sum=0;
i=1;
while(i<=10){
sum=sum+i;
i++;
}
循环不变式
for 语句
for (exp1; exp2; exp3)
语句 ;
exp3
exp2
非 0
0
循环条件
exp1
语 句
循环体
while (表达式 )
语句;
语 句
表达式
非 0
0
for (exp1; exp2; exp3)
语句 ;
exp3
exp2
非 0
0
exp1
语 句
exp1;
while(exp2){
语句 ;
exp3;
}
while 和 for
while 和 for
while (表达式 )
语句;
for (exp1; exp2; exp3)
语句 ;
exp1;
while(exp2{
语句 ;
exp3;
}
sum=0;
i=1;
while(i<=10){
sum=sum+i;
i++;
}
sum=0;
for(i=1; i<=10; i++)
sum=sum+i;
程序举例
例 T1-1 求 1+2+3+4+……+ n
例 T1-2 求 1+1/2+1/3+1/4+…… + 1/n
例 T1-3 求 1-1/2+1/3-1/4+…… 1/n
例 T1-4 求 1-1/3+1/5-1/6+…… 前 n项之和
例 T2-1 求 n!
例 T2-2 求 xn
例 T3-1 求 1-1/3+1/5-1/7+……, 直到最后 1项的绝对值 <10-5
例 T4-1 输入 100个整数, 求其中正数之和
例 T4-2 输入一个正整数 n,再输入 n个数, 输出最大值
例 T5 输出 Fibonacci序列前 20个数
例 T1-1 求 1+2+3+4+……+ n
算法:
i =1 to n
s=s+t
t++
i++
程序段:
s=0;
for(i=1; i<=n; i++)
s=s+i;
算法:
i =1 to n
s=s+i
i++
例 T1-2 求 1+1/2+1/3+……+ 1/ n
算法:
i =1 to n
s=s+t
t=1.0/i
i++
程序段:
s=0;
for(i=1; i<=n; i++)
s=s+1.0/i;
算法:
i =1 to n
s=s+t
t++
i++
例 T1-3 求 1-1/2+1/3-1/4+…… 1/ n
i =1 to n
s=s+t
t=1.0/i
i++ 程序段:
s=0; flag=1;
for(i=1; i<=n; i++){
s=s+1.0/i*flag;
flag=-flag;
}
算法:
i =1 to n
s=s+t
t=1.0/i*flag
flag=-flag
i++
例 T1-4 求 1-1/3+1/5-…… 前 n项和
算法:
i =1 to n
s=s+t
t=1.0/i*flag
flag=-flag
i++
程序段:
s=0;flag=1;tt=1;
for(i=1; i<=n; i++){
s=s+1.0/tt*flag;
tt+=2;
flag=-flag;
}
算法:
i =1 to n
s=s+t
t=1.0/tt*flag
flag=-flag
tt=tt+2
i++
例 T2-1 求 n!
算法:
i =1 to n
f=f*t
t++
i++
程序段:
f=1;
for(i=1; i<=n; i++)
f=f*i;
算法:
i =1 to n
f=f*i
i++
例 T2-2 求 xn
算法:
i =1 to n
f=f*t
t++
i++
程序段:
f=1;
for(i=1; i<=n; i++)
f=f*x;算法:
i =1 to n
f=f*t
t=x
i++
例 T3-1 求 1-1/3+1/5-… 直到最后 1项的绝对值 <10-5
程序段:
s=0; flag=1; tt=1; t=1;
while(fabs(t) >= 1E-5){
s = s+t;
flag = -flag;
tt += 2;
t = 1.0/tt*flag;
}
i =1 to n
s=s+t
t=1.0/tt*flag
flag=-flag
tt=tt+2
i++
算法:
while |t|>=1E-5
s=s+t
flag=-flag
tt=tt+2
t=1.0/tt*flag
例 T4-1 输入 100个整数,求其中正数之和
# include <stdio.h>
void main()
{
int i,sum=0,x;
for (i=0; i<100; i++){
scanf("%d",&x);
if (x>0) sum=sum+x;
}
printf("%d",sum);
}
例 4- 7 求最大值
输入 3个数, 输出其中的最大值 。
#include <stdio.h>
void main( )
{
int a,b,c,max;
printf("input a,b,c:\n");
scanf("%d%d%d",&a,&b,&c);
max = a;
if(max < b) max = b;
if(max < c) max = c;
printf("max is %d\n",max);
}
a max
b
c
max
max
例 T4-1输入一个正整数 n,再输入 n个数,输出最大值
void main()
{ int i,max,n,x;
scanf("%d",&n);
if(n>=1){
scanf("%d",&x);
max=x;
for (i=1; i<n; i++){
scanf("%d",&x);
if (max < x) max=x;
}
printf("%d",max);
}
}
x max
max
x
例 T5 输出 Fibonacci序列前 20个数
1,1,2,3,5,8,……
x1 x2 t
x1 x2 t
程序段:
x1=x2=1;
printf("%d %d",x1,x2);
for(i=1; i<=18; i++){
t=x1+x2;
printf("%d ",t);
x1=x2; x2=t;
}
x1=x2=1;
t=x1+x2;
x1=x2;
x2=t;
do-while 语句
do 语句
while (表达式 );
i=1;
do {
printf("%d",i);
i++;
} while(i<=10);
语 句
表达式
非 0
0
while (表达式 )
语句;
语 句
表达式
非 0
0
while 和 do-while
do 语句
while (表达式 );
语 句
表达式
非 0
0
先循环
后判断
先判断
后循环
while 和 do-while 的用法比较
输入一些数,求和,直到输入负数为止。
void main( )
{
int x,sum=0;
do{
scanf("%d",&x);
sum + = x;
} while (x>0);
printf("sum=%d",sum);
}
void main( )
{
int x,sum=0;
scanf("%d",&x);
while (x>0){
sum + = x;
scanf("%d",&x);
};
printf("sum=%d",sum);
}输入 1 2 5 -10
输入 -10 1 2 5
sum-x
5.2 break 和 continue 语句
#include "stdio.h"
void main( )
{
char c;
int i=0;
for (i=0; i<10;i++) {
c=getchar();
if (c=='\n') break;
putchar(c);
}
}
循环何时结束?
c=getchar();
for (i=0; i<10 && c! ='\n'; i++){
putchar(c);
c=getchar();
}
for (i=0; ;i++) {
c=getchar();
if ( i >= 10 || c == '\n) break;
putchar(c);
}
1
break 流程
结束循环
while(exp){
语句 1
if (expb) break;
语句 2
}
非 0
0
exp
语句 1
0expb
语 句 2



非 0
continue 流程
跳过 continue后面的语句,
继续下一次循环
while(exp){
语句 1
if (expc) continue;
语句 2
}
非 0
0
exp
语句 1
0expb
语 句 2



非 0
break 和 continue
#include "stdio.h"
void main( )
{
char c;
int i=0;
for (i=0; i<10;i++) {
c=getchar();
if (c=='\n') break;
putchar(c);
}
}
#include "stdio.h"
void main( )
{
char c;
int i=0;
for (i=0; i<10;i++) {
c=getchar();
if (c=='\n') continue;
putchar(c);
}
}
输入,abc ↙
efgh ↙
123 ↙
输出,abcefgh1输出,abc
例 T6 输入 m,判断 m是否为素数
算法:除了 1和 m,不能被其它数整除 。
m %2 %3 %4 %5
不是素数 || =0 =0
是素数 && !=0 !=0
程序段:
n=sqrt(m);
for(i=2; i<=n; i++)
if(m%i==0) break;
if(i>n) printf("yes\n")
else printf("no\n”);
例 T7 将一个正整数逆序输出
确定,循环条件 和 循环不变体
12345 5 4 3 2 1
12345 % 10 = 5 12345 / 10 = 1234
1234 % 10 = 4 1234 / 10 = 123
123 % 10 = 3 123 / 10 = 12
12 % 10 = 2 12 / 10 = 1
1 % 10 = 1 1 / 10 = 0 结束
循环不变式 x%10 x=x/10
循环条件 x==0
scanf(,%d”,&x);
while (x!=0){
digit = x %10;
x = x/10 ;
printf(,%d,,digit);
}
例 4-10
# include <stdio.h>
void main( )
{ char c;
printf("Please input a character:\n");
c = getchar();
if(c>='a' && c <= 'z' || c>='A' && c <= 'Z')
printf("This is a letter.\n");
else if(c>='0' && c <= '9')
printf("This is a digit.\n");
else
printf("This is an other character,\n");
}
输入一行字符, 统计英文字母, 数字和其他字符 。
例 T8 输入一行字符,统计英文字母、数字和其他字符
# include <stdio.h>
void main( )
{ char c;
int letter=0,digit=0,other=0;
c = getchar();
while(c!='\n'){
if(c>='a' && c <= 'z' || c>='A' && c <= 'Z')
letter++;
else if(c>='0' && c <= '9')
digit++;
else
other++;
c=getchar();
}
printf("%d %d %d",letter,digit,other);
}
while((c = getchar())!='\n')
5.3 循环嵌套
while (表达式 )
语句 ; 循环语句
例 T9-1.1 1!+2!+……+n!
s=0;
for(k=1; k<=n; k++){
s=s+f;
} f=1; /* n! */for(i=1; i<=n; i++)
f=f*i;
f=1;
for(i=1; i<=k; i++)
f=f*i;
算法:
k=1 to n
s = s + f
f = k!
k++
例 T9-1.2 1!+2!+……+n!
算法:
k=1 to n
s = s + f
f = k!
k++
s=0;f=1;
for(k=1;k<=n;k++){
f=f*k;
s=s+f;
}
算法:
k =1 to n
s = s+f
f = f*k
k++
例 T9-2 兑换零钱
将 10元钱换成 5角,2角,1角的零钱 (至少各一枚 ),
列出所有可能的方案。
c5,5角的数量,[1,20)
c2,2角的数量,[1,50)
c1,1角的数量,[1,100)
5*c1+2*c2+c5==100
将 10元钱换成 5角,2角,1角的零钱
c5,5角的数量,[1,20)
c2,2角的数量,[1,50)
c1,1角的数量,[1,100)
5*c5+2*c2+c1==100
for (c5=1; c5<20; c5++)
for (c2=1; c2<50; c2++)
for (c1=1; c1<100; c1++)
if (5*c5+2*c2+c1==100 )
printf("%d %d %d\n",c5,c2,c1);
c5=1
c2=1
c1=1 ? 99
2 ? 49
2 ? 19
将 10元钱换成 5角,2角,1角的零钱
c5,5角的数量,[1,20)
c2,2角的数量,[1,50)
c1,1角的数量,[1,100)
5*c5+2*c2+c1==1000
for (c5=1; c5<20; c5++)
for (c2=1; c2<50; c2++)
for (c1=1; c1<100; c1++)
if (5*c5+2*c2+c1==1000 )
printf("%d %d %d\n",c5,c2,c1);
for (c5=1; c5<20; c5++)
for (c2=1; c2<50; c2++)
printf("%d %d %d\n",c5,c2,1000- 5*c5+2*c2);
例 T9-3 输出 100~200间所有素数
算法:
m =100 to 200
if m是素数
print m
n=sqrt(m);
for(i=2; i<=n; i++)
if(m%i==0) break;
if(i>n) printf("yes\n")
else printf("no\n”);
for(m=100; m<=200; m++){
n=sqrt(m);
for(i=2; i<=n; i++)
if(m%i==0) break;
if(i>n) printf("%d",m)
}
5.3 循环嵌套
循环嵌套均是大循环嵌小循环
绝对不允许循环体交叉 !
for ( ){
.........
do {
..........
}
} while(....)
for ( ) {
........,
do {
} while( )
}
5.3 循环嵌套
break 与 循环
for ( ){
.........
while( ){
..........
break;
..........
}
.........
}