重庆工学院计算机科学与工程学院基础系5
第五章循环程序设计第五章 循环程序设计
2009年 7月 27日星期一2 重庆工学院计算机学院 基础系在 C语言中可用以下语句构成循环:
if? goto
while
do? while
for
其中 if? goto是通过编程技巧 (if语句和 goto语句组合 )构成循环功能。而且 goto语句将影响程序流程的模块化,使程序可读性变差,所以结构化程序设计主张限制 goto语句的使用。
其他三种语句是 C语言提供的循环结构专用语句。
第五章 循环程序设计
2009年 7月 27日星期一3 重庆工学院计算机学院 基础系
循环结构两大要素:
循环条件 p
结束循环的条件表达式
循环体 A
循环执行的语句或语句组
设置循环条件要特别注意确定:
循环变量 的 初值
循环变量 的 终值
循环变量 的 变化规律名词解释无限循环死循环名词解释空循环第五章 循环程序设计
2009年 7月 27日星期一4 重庆工学院计算机学院 基础系
【 例二 】
main()
{
int n=0,sum=0;
loop,if (sum>=10000)
goto end;
sum+=n;
++n;
goto loop;
end:printf(“n = %d\n”,n);
}
直到型当型1,if … goto语句循环结构【 例一 】main()
{
int n=0,sum=0;
loop,sum+=n;
++n;
if (sum<=10000)
goto loop;
printf(“n = %d\n”,n);
}
第五章 循环程序设计
2009年 7月 27日星期一5 重庆工学院计算机学院 基础系
2,while语句循环结构
【 例三 】
main()
{
int n=0,sum=0;
while (sum<=10000)
{
sum+=n;
++n;
}
printf(“n = %d\n”,n);
}
当型
一般形式
while (条件表达式 ) 循环体;
用于构成当型循环:先判断后执行 /条件为真继续循环,直到条件为假时结束循环。
【 注意 】 条件表达式或循环体内应有改变条件使循环结束的语句,否则可能陷入“死循环”。
第五章 循环程序设计
2009年 7月 27日星期一6 重庆工学院计算机学院 基础系
3,do… while语句循环结构
【 例四 】
main()
{
int n=0,sum=0;
do {
sum+=n;
++n;
} while (sum<=10000)
printf(“n = %d\n”,n);
}
一般形式
do {
循环语句(组)
} while ( 条件表达式 );
用于构成直到型循环:先执行后判断 /条件为真继续循环,直到条件为假时结束循环。
【 注意 】 条件表达式或循环体内同样应有改变条件使循环结束的语句,否则可能陷入“死循环”。
直到型直到 sum超过
10000为止第五章 循环程序设计
2009年 7月 27日星期一7 重庆工学院计算机学院 基础系
【 例五 】 从键盘输入一个整数
12456,分析以下程序运行结果。
main()
{
int num,c;
printf(“请输入一个整数,“);
scanf(“%d”,&num);
do {
c=num%10;
printf(“%d”,c);
} while((num/=10)>0);
printf(“\n”);
}
/*取得 num的个位数 */
/*输出 num的个位数 */
/*直到 num/10为 0*/
结果:
65421
将各位数字反序显示出来
3,do… while语句循环结构 示例第五章 循环程序设计
2009年 7月 27日星期一8 重庆工学院计算机学院 基础系
4,for语句循环结构
一般形式
– for (表达式 1;条件表达式;表达式 3)
– 循环语句(组);
用于构成计数型当型循环:先判断后执行 /条件为真继续循环,直到条件为假时结束循环。
表达式 1,整个循环中只执行 1次,常用来对循环变量设置初值
条件表达式(表达式 2),其值为真
(非 0)时继续执行循环语句(组),
否则结束循环
表达式 3,常用于循环变量值的更新 (循环体的一部分每次循环语句组执行完后执行一次 )
【 例六 】
求 ∑i =1+2+3+4? +99+100
(i=1~ 100)
main()
{
int i,s=0;
for (i=1;i<=100;i++)
s=s+i;
printf(“Sum=%d\n”,s);
}
第五章 循环程序设计
2009年 7月 27日星期一9 重庆工学院计算机学院 基础系
5、其他循环控制结构
main( )
{
int a,y;
a=10,y=0;
do {
a+=2;y+=a;
if (y>50) break;
} while (a=14);
printf("a=%d,y=%d\n",a,y);
}
结果,a=16,y=60
变量跟踪
a y
10 0
12 12
12+2 12+14=26
14+2 16+26=42
16+2 16+42=5
变量跟踪分析法
break 结束循环
– 在 switch中退出 switch结构;
– 在循环中结束循环。
continue 结束本次循环
– 循环“短路” (跳过循环体后面的语句,开始下一轮循环 )。
goto 跳转
– 跳到循环体外指定标号处。
【 注意 】
– goto 语句只能从循环内向外跳转,反之不可!基础系第五章 循环程序设计
2009年 7月 27日星期一10 重庆工学院计算机学院 基础系
5、其他循环控制结构
break 结束循环
– 在 switch中退出 switch结构;
– 在循环中结束循环。
continue 结束本次循环
– 循环“短路” (跳过循环体后面的语句,开始下一轮循环 )。
goto 跳转
– 跳到循环体外指定标号处。
【 注意 】
– goto 语句只能从循环内向外跳转,反之不可!基础系求以下程序段执行后 x和 i的值。
int i,x;
for ( i=1,x=1;i<=50;i++)
{ if (x>=10) break;
if (x%2==1)
{ x+=5;
continue;
}
x-=3;
}
结果,x的值为 10,i的值为 6
变量跟踪
i x
1 1→6
2 6→3
3 3→8
4 8→5
5 5→10
6
第五章 循环程序设计
2009年 7月 27日星期一11 重庆工学院计算机学院 基础系
5、其他循环控制结构
break 结束循环在 switch中退出 switch结构;
在循环中结束循环。
continue 结束本次循环循环“短路” (跳过循环体后面的语句,开始下一轮循环 )。
goto 跳转跳到循环体外指定标号处。
【 注意 】
goto 语句只能从循环内向外跳转,反之不可!
main()
{
int i=1;
while (i<=15)
if (++i%3!=2)
continue;
else
printf("%d ",i);
printf("\n");
}
结果,2 5 8 11 14
变量跟踪
i ++i%3 输出 i
1→2 2 2
2→3 0
3→4 1
4→5 2 5
5→6 0

第五章 循环程序设计
2009年 7月 27日星期一12 重庆工学院计算机学院 基础系
5、其他循环控制结构
break 结束循环在 switch中退出 switch结构;
在循环中结束循环。
continue 结束本次循环循环“短路” (跳过循环体后面的语句,开始下一轮循环 )。
goto 跳转跳到循环体外指定标号处。
【 注意 】
goto 语句只能从循环内向外跳转,反之不可!
main()
{
int i,k=0;
for (i=1; ;i++)
{ k++;
while (k<i*i)
{ k++;
if (k%3==0)
goto loop;
}
}
loop:printf("%d,%d",i,k);
}
结果,2,3
第五章 循环程序设计
2009年 7月 27日星期一13 重庆工学院计算机学院 基础系循环常用算法
1、枚举法(穷举法)
,笨人之法,,把所有可能的情况一一测试,筛选出符合条件的各种结果进行输出。
【 例一 】 百元买百鸡,用一百元钱买一百只鸡。已知公鸡 5元 /只,母鸡 3元 /只,小鸡 1元 /3只。
分析:
这是个不定方程 ——三元一次方程组问题(三个变量,两个方程)
x+ y+ z=100
5x+ 3y+ z/3=100
设公鸡为 x只,母鸡为 y只,小鸡为 z只。
第五章 循环程序设计
2009年 7月 27日星期一14 重庆工学院计算机学院 基础系百元买百鸡问题分析第五章 循环程序设计
2009年 7月 27日星期一15 重庆工学院计算机学院 基础系
main()
{
int x,y,z;
for (x=0;x<=100;x++)
for (y=0;y<=100;y++)
for (z=0;z<=100;z++)
{
if (x+y+z==100 && 5*x+3*y+z/3.0==100 )
printf("cocks=%d,hens=%d,chickens=%d\n",x,y,z);
}
}
结果,x=0,y=25,z=75
x=4,y=18,z=78
x=8,y=11,z=81
x=12,y=4,z=84
【 讨论此为“最笨”之法 ——要进行 101× 101× 101= 1030301次
( 100多万次)运算。
百元买百鸡问题分析第五章 循环程序设计
2009年 7月 27日星期一16 重庆工学院计算机学院 基础系百元买百鸡问题分析
main()
{
int x,y,z;
for (x=0;x<=100;x++)
for (y=0;y<=100;y++)
{
z=100-x-y;
if (5*x+3*y+z/3.0==100 )
printf(“cocks=%d,hens=%d,chickens=%d\n",x,y,z);
}
}
【 讨论 】
令 z=100-x-y 只进行 101× 101= 10201 次运算(前者的
1%)
取 x<=19,y<=33 只进行
20× 34= 680 次运算(第
1种运算的 6.7%)
第五章 循环程序设计
2009年 7月 27日星期一17 重庆工学院计算机学院 基础系
【 例二 】 雨水淋湿了算术书的一道题,8个数字只 能看清 3个,第一个数字虽然看不清,
但可看出不是 1。编程求其余数字是什么?
[ □ × (□ 3+□) ]2 = 8□□ 9
分析设分别用 A,B,C,D,E五个变量表示自左到右五个未知的数字。其中 A的取值范围为 2~ 9,
其余取值范围为 0~ 9。条件表达式即为给定算式。
第五章 循环程序设计
2009年 7月 27日星期一18 重庆工学院计算机学院 基础系
main() {
int A,B,C,D,E;
for (A=2;A<=9;A++)
for (B=0;B<=9;B++)
for (C=0;C<=9;C++)
for (D=0;D<=9;D++)
for (E=0;E<=9;E++)
if (A*(B*10+3+C)*A*(B*10+3+C)==8009+D*100+E*10)
printf(“%2d%2d%2d%2d%2d\n”,A,B,C,D,E);
}
结果,3 2 8 6 4
【 例二 】 雨水淋湿了算术书的一道题,8个数字只 能看清 3个,第一个数字虽然看不清,但可看出不是 1。编程求其余数字是什么?
[ □ × (□ 3+□) ]2 = 8□□ 9
第五章 循环程序设计
2009年 7月 27日星期一19 重庆工学院计算机学院 基础系
【 例三 】
求 100~ 200之间不能被 3整除也不能被 7整除的数。
分析,求某区间内符合某一要求的数,
可用一个变量“穷举”。所以可用一个独立变量 x,取值范围 100~ 200。
for (x=100;x<=200;x++)
if (x%3!=0&&x%7!=0)
printf(“x=%d\n”,x);
如果是求指定条件的奇数呢?
如果是求指定条件的偶数呢?
x=101;x<=200;x=x+2
x=100;x<=200;x=x+2
第五章 循环程序设计
2009年 7月 27日星期一20 重庆工学院计算机学院 基础系
2、归纳法(递推法)
“智人之法”,通过分析归纳,找出从变量旧值出发求新值的规律。
【 例一 】
编程求 ∑i =1+2+3+4…+99+100 (i=0 ~ 100)
分析
i=0 S0= 0 (初值 )
i=1 S1= 0+1=S0+1
i=2 S2=1+2=S1+2
i=3 S3=1+2+3=S2+3
i=4 S4=1+2+3+4=S3+4

i=n Sn=1+ 2+3+4+? +n=Sn-1+n
第五章 循环程序设计
2009年 7月 27日星期一21 重庆工学院计算机学院 基础系
【 例一 】
编程求 ∑i =1+2+3+4? +n ( n ≤100)
程序:
main()
{
int i,n,s=0;
printf("n=");
scanf("%d",&n);
for ( i=1;i<=n;i++)
s=s+i;
printf("Sum=%d\n",s);
}
运行结果:
n=100
Sum=5050
如果是
∑i =1+1/2+1/3+? +1/n 呢?
第五章 循环程序设计
2009年 7月 27日星期一22 重庆工学院计算机学院 基础系算法类型小结,累加型
【 累加型 】 类型诸如
□ +□ +□ +□ +……+ □ +□
求其前 n项之和的编程题。
累加型算法若设 i为循环变量,s为前 n项累加之和,
则程序的基本结构为:
s=0;
for( i=1 ;i<=n ;i++ )
s=s+□ ;
第五章 循环程序设计
2009年 7月 27日星期一23 重庆工学院计算机学院 基础系
【 例二 】
编程求 1- 1/2+1/3- 1/4+1/5-? +1/99- 1/100
分母为奇数时,相加
分母为偶数时,相减法 1,从变化规律分析
程序:
main()
{
int i;
float s=0;
for (i=1;i<=100;i++)
if (i%2) s=s+1/i;
else s=s-1/i;
printf("Sum=%f\n",s);
}
运行结果,Sum=1.000000
错在哪里?
第五章 循环程序设计
2009年 7月 27日星期一24 重庆工学院计算机学院 基础系
【 例二 】
编程求 1- 1/2+1/3- 1/4+1/5-? +1/99- 1/100
法 2,这是个累加型算法的编程题程序:
#include <math.h> main();
{
int i ;
float s=0;
for (i=1;i<=100;i++)
s=s+pow (-1,i+1) / i ;
printf("Sum=%f\n",s);
}
程序:
#include <math.h>
main()
{
int i,k=1; float s=0;
for (i=1;i<=100;i++)
{ s=s+ k / i ;
k = -k ; }
printf("Sum=%f\n",s);
}
累加型算法程序基本结构为:
s=0;
for( i=1;i<=n;i++ )
s=s+□ ;
错在哪里?
(如何检查程序错误? )
运行结果,Sum=0.688172
运行结果,Sum=1.000000
第五章 循环程序设计
2009年 7月 27日星期一25 重庆工学院计算机学院 基础系
【 例三 】
编程求 n! ( n由键盘输入)
分析
i=0 S0= 1=S0 (初值 )
i=1 S1= 0× 1=S0× 1
i=2 S2=1× 2=S1× 2
i=3 S3=1× 2× 3=S2× 3
i=4 S4=1× 2× 3× 4=S3× 4

i=n Sn=1× 2× 3× 4×? × n=Sn-1× n
第五章 循环程序设计
2009年 7月 27日星期一26 重庆工学院计算机学院 基础系
【 例三 】
编程求 n! ( n由键盘输入)
程序:
main()
{
int i,n,s=1;
printf("n=");
scanf("%d",&n);
for ( i=1;i<=n;i++)
s=s*i;
printf("Sum=%d\n",s);
}
运行结果:
n=5
Sum=120
运行结果:
n=8
Sum=-25216
Why?
第五章 循环程序设计
2009年 7月 27日星期一27 重庆工学院计算机学院 基础系算法类型小结,阶乘型
【 阶乘型 】 类型诸如
□ ×□×□×□× …… ×□×□
求其前 n项之积的编程题。
阶乘型算法若设 i为循环变量,s为前 n项相乘之积,则程序的基本结构为:
s=1;
for( i=1 ;i<=n ;i++ )
s=s*□ ;
第五章 循环程序设计
2009年 7月 27日星期一28 重庆工学院计算机学院 基础系
【 例四 】
编程求 ∑i! =1!+2!+3!? +n! ( n由键盘输入)
外循环为累加型
内循环为阶乘型法 1,从变化规律分析
程序:
main()
{
int i,j,n ;
float s,s1;
printf ( "请输入 n=") ;
scanf ( "%d",&n);
s=0;
for (i=1;i<=n;i++)
{
s1=1;
for (j=1; j<=i ; j++)
s1=s1*j ;
s=s+s1;
}
printf ( "Sum=%.0f\n",s) ;
}
运行结果:
n=5
Sum=153
/*如果 n值较大,可改为 printf (,Sum=%e\n”,s) ;*/
第五章 循环程序设计
2009年 7月 27日星期一29 重庆工学院计算机学院 基础系
【 例四 】
编程求 ∑n! =1!+2!+3!? +n! ( n由键盘输入)
在同一个循环中先阶乘,后累加法 2,通过单循环实现
程序:
main()
{
int i,n ;
float s,s1;
printf ( "请输入 n=") ;
scanf ( "%d",&n);
s=0,s1=1;
for (i=1;i<=n;i++)
{
s1=s1* i ;
s=s+s1;
}
printf ( "Sum=%.0f\n",s) ;
}
运行结果:
n=5
Sum=153
第五章 循环程序设计
2009年 7月 27日星期一30 重庆工学院计算机学院 基础系
【 例五 】
兔子繁殖问题(斐波那契数列问题)
著名意大利数学家斐波那契( Fibonacci) 1202年提出一个有趣的问题。某人想知道一年内一对兔子可以生几对兔子。他筑了一道围墙,把一对大兔关在其中。
已知每对大兔每个月可以生一对小兔,而每对小兔出生后第三个月即可成为
,大兔,再生小兔。问一对小兔一年能繁殖几对小兔?
分析:▲表示大兔,△表示小兔由分析可以推出,每月新增兔子数 Fn={1,1,2,3,5,8,13,21,34,…}
(斐波那契数列)
月份 n 兔子数 Fn
1 F1=1
2 F2=1
3 F3=2=F1+F2
4 F4=3=F2+F3
5 F5=5=F3+F4

n Fn=Fn-1+Fn-2
第五章 循环程序设计
2009年 7月 27日星期一31 重庆工学院计算机学院 基础系
【 例五 】 例 5.12
兔子繁殖问题(斐波那契数列问题) main(){
int f1=1,f2=1,f,i,s,n;
clrscr();
printf("请输入月数,");
scanf("%d",&n);
for (s=2,i=3;i<=n;i++)
{
f=f1+f2;
s=s+f;
f1=f2;
f2=f;
}
printf("%d个月的兔子数是 %d\n",n,s);
}
第五章 循环程序设计
2009年 7月 27日星期一32 重庆工学院计算机学院 基础系
【 例六 】
编程显示以下图形(共 N 行,N 由键盘输入)。
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
此类题目分析的要点是:
通过分析,找出每行空格、
* 与行号 i、列号 j及总行数 N的关系。
其循环结构可用右图表示。
分析,(设 N=5)
第 1行 4个空格 =5-1 1个,*” =2*行号 -1
第 2行 3个空格 =5-2 3个,*” =2*行号 -1
第 3行 2个空格 =5-3 5个,*” =2*行号 -1
第 4行 1个空格 =5-4 7个,*” =2*行号 -1
第 5行 0个空格 =5-5 9个,*” =2*行号 -1
由此归纳出:第 i行的空格数 N-i个;
第 i行的,*” 数是 2i-1个。
第五章 循环程序设计
2009年 7月 27日星期一33 重庆工学院计算机学院 基础系
【 例六 】
main()
{
int i,j,N;
clrscr();
printf ("请输入 N=") ;
scanf("%d",&N);
for ( i=1 ; i<=N ; i++)
{
for (j=1; j<=N - i; j++)
printf(" ");
for (j=1; j<=2* i -1; j++)
printf("*");
printf("\n");
}
}
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
第五章 循环程序设计
2009年 7月 27日星期一34 重庆工学院计算机学院 基础系除了以上例题,要求根据教材掌握:
1、求按指定精度近似值问题(例 6.6)
2、判断一个数是否素数问题(例 6.8)
3、密码问题(例 6.10)
第五章 循环程序设计
2009年 7月 27日星期一35 重庆工学院计算机学院 基础系判断一个数是否素数问题(例 6.8
另一种解法)
#include <math.h>
main()
{
int m,k,i;
clrscr();
printf("x=");
scanf("%d",&m);
for(i=2;i<m-1;i++)
if (m%i==0)
{
printf("%d is not a prime number\n",m);
exit(0);
}
printf("i=%d,%d is a prime number\n",i,m);
}
把 i<m-1
改为 i<sqrt(m-1)
比较 i的值第五章 循环程序设计
2009年 7月 27日星期一36 重庆工学院计算机学院 基础系小结
1,循环是一组语句,计算机反复执行这组语句直到满足终止条件为止。
2,while,do…,while和 for 三种循环语句可以相互转化。
3,for适用于循环次数已知的循环。
4,while先判定循环条件,可能一次都不执行循环体。
5,do… while后判定循环条件,至少保证执行一次循环体。
6,while和 do… while中都有改变循环控制变量的语句。
7,可以通过循环变量来控制循环,在循环体中通过条件
8,判定产生中间跳转的方法,终止循环。