530 likes | 702 Views
第 5 章. 循环结构程序设计. int result1,result2,result3; int result4,result5; result1 = 1 * 10; printf("1 × 10 = %d <br>",result1); result2 = 2 * 10; printf("2 × 10 = %d <br>",result2); result3 = 3 * 10; printf("3 × 10 = %d <br>",result3); result4 = 4 * 10; printf("4 × 10 = %d <br>",result4);
E N D
第5章 循环结构程序设计 公共计算机基础教研部
int result1,result2,result3; int result4,result5; result1 = 1 * 10; printf("1 × 10 =%d \n",result1); result2 = 2 * 10; printf("2 × 10 =%d \n",result2); result3 = 3 * 10; printf("3 × 10 =%d \n",result3); result4 = 4 * 10; printf("4 × 10 =%d \n",result4); result5 = 5 * 10; printf("5 × 10 =%d \n",result5); 5.1 循环的概念 循环的必要性 1 × 10 =10 2 × 10 =20 3 × 10 =30 4 × 10 =40 5 × 10 =50 输出结果 重复语句 公共计算机基础教研部
5.1 循环的概念 循环的必要性 1 × 10 = 10 2 × 10 = 20 3 × 10 = 30 4 × 10 = 40 5 × 10 = 50 0 + 1 1 + 1 2 + 1 上个数字 + 1 ... 重复 (上个数字 +1) × 10 公共计算机基础教研部
C 语言中的各种循环 do- while for while 需要多次重复执行一个或多个任务的问题考虑使用 循环来解决 公共计算机基础教研部
不成立 表达式? 成立 循环体语句 执行while循环之后的语句 5.2 用while语句和do...while语句 实现循环 5.2.1 用while语句实现循环 • 执行流程: • 一般形式: while(表达式) { 循环体语句; } 说明:如是单条语句,花括号可以省略。 公共计算机基础教研部
<例> 用while循环求 5.2 用while语句和do...while语句 实现循环 #include <stdio.h> main() { int i, sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } sum=0+1 sum=1+2=3 sum=3+3=6 sum=6+4 …… sum=4950+100=5050 公共计算机基础教研部
i1; sum0 <例> 用while循环求 当 i<=100 sumsum+1 i++ 循环条件 循环初值 输出sum 循环变量增值 循环终值 循环体 5.2 用while语句和do...while语句 实现循环 #include <stdio.h> main() { int i, sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } 公共计算机基础教研部
循环体 真(非0) expr 假(0) 5.2 用while语句和do...while语句 实现循环 5.2.2用do...while语句实现循环 • 一般形式: • 执行流程: do { 循环体语句; }while(表达式); • 特点:先执行循环体,后判断表达式 • 说明: • 至少执行一次循环体 公共计算机基础教研部
do-while 循环示例 main() { int number=5, guess; printf ("猜一个介于 1 与 10 之间的数\n"); do { printf("请输入您猜测的数:"); scanf("%d",&guess); if (guess > number) printf("太大\n"); else if (guess < number) printf("太小\n"); } while (guess != number); printf("您猜中了! 答案为 %d\n",number); } 猜一个介于 1 与 10 之间的数 请输入您猜测的数:3 太小 请输入您猜测的数:5 您猜中了! 答案为 5 问题描述: 猜数游戏。要求猜一个介于1~10之间的数字,根据用户猜测的数与标准值进行对比,并给出提示,以便下次猜测能接近标准值,直到猜中为止。 输入数字 5 后,do…while 循环中的条件为假,输出结果消息后,程序终止。 公共计算机基础教研部
#include <stdlib.h> do-while 循环示例 main() { int number=5, guess; printf ("猜一个介于 1 与 10 之间的数\n"); do { printf("请输入您猜测的数:"); scanf("%d",&guess); if (guess > number) printf("太大\n"); else if (guess < number) printf("太小\n"); } while (guess != number); printf("您猜中了! 答案为 %d\n",number); } int number; number=rand(); number=rand()%100; srand( time(0) ); 产生一个0~100间的伪随机数 公共计算机基础教研部
5.2 用while语句和do...while语句 实现循环 5.2.3 whlie和do...while循环的比较 • 凡是能用while循环处理,都能用do…while循环处理。do…while循环结构可以转换成while循环结构。 • 在一般情况下,用while语句和用do-while语 句处理同一问题时,若二者的循环体部分是一 样的,它们的结果也一样。但是如果while后面 的表达式一开始就为假(0值)时,两种循环的结 果是不同的。 公共计算机基础教研部
<例> while和do-while循环的比较(1) (2) main ( ) 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); } } 运行结果: 1↙ sum=55 再运行一次: 11↙ sum=0 运行结果: 1↙ sum=55 再运行一次: 11↙ sum=11 说明:当while后面的表达式的第一次的值为“真”时,两种循环得到的结果相同。否则,二者结果不相同。 公共计算机基础教研部
5.2 用while语句和do...while语句 实现循环 5.2.4 whlie循环程序举例 • 求1+2+3+········+100 • 求1-2+3-4+5-6+········-100 • 求1+3+5+·······+99 • 求1+1/3+1/5+·······+1/99 • 求1-1/3+1/5-······· -1/97+1/99 公共计算机基础教研部
5.2 用while语句和do...while语句 实现循环 5.2.4 whlie循环程序举例 <例>用π/4≈1-1/3+1/5-1/7+…公式求π的近似值,直到某一项的绝对值小于为止。 N-S图表示算法 公共计算机基础教研部
运行结果: pi= 3.141594 <例> 求pi的近似值#include<math.h>void main(){ int s; float n,t,pi; t=1; pi=0; n=1.0; s=1; while(fabs(t)>1e-6) { pi=pi+t; n=n+2; s=-s; t=s/n; } pi=pi*4; printf(″pi=%10.6f\n″,pi);} 公共计算机基础教研部
5.3 用for语句实现循环 5.3.1 for语句的一般形式和执行过程 • 一般形式: • 执行流程: expr1 for(expr1 ; expr2 ; expr3) { 循环体语句; } 假(0) expr2 真(非0) 循环体 expr3 公共计算机基础教研部
5.3 用for语句实现循环 for 循环的一般语法: for( 表达式1 ; 表达式2 ; 表达式3 ) { 语句; } 1 2 4 3 counter = 0; num = 1; cnt = 100; 工作原理 counter == 10; num < 25; cnt >0 counter ++; num = num + 1; cnt-- 1、计算表达式1的值,通常为循环变量赋初值; 2、计算表达式2的值,即判断循环条件是否为真,若值为真则执行循环体一次, 否则跳出循环; 3、计算表达式3的值,这里通常写更新循环变量的赋值表达式,然后转回第2步重复执行; 分号用于分隔 for 循环的 三个表达式 公共计算机基础教研部
表达式1 N 表达式2 表达式3 语句 5.3 用for语句实现循环 NS图与流程图 表达式1 表达式1 表达式2 表达式2 表达式2 N 语句 Y 表达式3 Y 表达式3 公共计算机基础教研部
内存 number fac i 5.3 用for语句实现循环 for 循环示例 #include <stdio.h> void main() { int number,i,fac=1; printf("\n 请输入任意一个正整数:"); scanf("%d",&number); for(i = 1; i<=number; i++) fac=fac*i; printf("\n %d的阶乘= %d\n",number,fac); } 2 6 5 1 120 1 循环执行五次 请输入任意一个正整数:5 5的阶乘 = 120 公共计算机基础教研部
for 循环中有三个表达式 for 语句中的各个表达式都可以省略 分号分隔符不能省略 5.3 用for语句实现循环 5.3.2 for语句的各种形式 可省略 for(<初始化循环变量> ;<循环条件> ; <修改循环变量的值>) { <循环体语句>; } 不能省略 公共计算机基础教研部
5.3 用for语句实现循环 • for语句可以转换成while结构 for(expr1 ; expr2 ; expr3) 循环体语句; expr1; while(expr2) { 循环体语句; expr3; } 公共计算机基础教研部
<例>:求Fibonacci数列前20个数。这个数列有如下特点:第1,2两个数为1,1。从第3个数开始,该数是其前面两个数之和。即:<例>:求Fibonacci数列前20个数。这个数列有如下特点:第1,2两个数为1,1。从第3个数开始,该数是其前面两个数之和。即: F(1)=1 (n=1) F(2)=1 (n=2) F(n)=F(n-1)+F(n-2) (n≥3) 5.3 用for语句实现循环 5.3.3 for循环程序举例 与书上的程序代码不一样 公共计算机基础教研部
<例>:求Fibonacci数列前20个数。这个数列有如下特点:第1,2两个数为1,1。从第3个数开始,该数是其前面两个数之和。即:<例>:求Fibonacci数列前20个数。这个数列有如下特点:第1,2两个数为1,1。从第3个数开始,该数是其前面两个数之和。即: F(1)=1 (n=1) F(2)=1 (n=2) F(n)=F(n-1)+F(n-2) (n≥3) f1 f2 f3 2 3 1 1 =f1+f2 第一轮操作 第二轮操作 以此类推 f1 f2 f3=f1+f2 公共计算机基础教研部
f1 f2 f3 2 3 1 1 =f1+f2 main() { int f1=1,f2=1,f3,i; printf(“%5d%5d”, f1, f2); for(i=3;i<=20;i++) { f3=f1+f2; printf(“%5d”, f3); f1=f2; f2=f3; if(i%5==0) printf(“\n”); } } f1 f2 f3=f1+f2 公共计算机基础教研部
外循环 内循环 内循环 4.5 循环的嵌套 • 定义:一个循环体内又包含了另一个完整的循环结构 • 三种循环可互相嵌套,层数不限 (4) for( ; ;) { …… do { …… }while(); …… while() { …… } …... } (1) while() { …… while() { …… } …... } (2) do { …… do { …… }while( ); …... }while( ); (3) while() { …… do { …… }while( ); ……. } 公共计算机基础教研部
4.5 循环的嵌套 程序举例 main() { int i,j; for(i=1;i<=2;i++) { printf(“\ni=%d\n”,i); for(j=1;j<=3;j++) printf(“j=%d,”,j); } } 公共计算机基础教研部
4.5 循环的嵌套 程序举例 main() { int i,j; for(i=1;i<=2;i++) { printf(“\ni=%d\n”,i); for(j=1;j<=3;j++) printf(“j=%d,”,j); } } 内层循环终止 j=2 j=4 j=3 公共计算机基础教研部
4.5 循环的嵌套 程序举例 循环全部终止 main() { int i,j; for(i=1;i<=2;i++) { printf(“\ni=%d\n”,i); for(j=1;j<=3;j++) printf(“j=%d,”,j); } } i=2 i=3 运行结果: 公共计算机基础教研部
4.5 循环的嵌套 <例>读程序,分析程序运行结果。 main() { int i, j; for(i=1; i<=9; i++) { for(j=1;j<=9;j++) printf(“%2d*%2d=%2d”, i, j, i*j); printf(“\n”); } } printf(“%3d”, i*j); 公共计算机基础教研部
4.5 循环的嵌套 <例>修改上例,实现如下三角形九九乘法表。 1 2 4 3 6 9 4 8 12 16 5 10 15 20 25 6 12 18 24 30 36 7 14 21 28 35 42 49 8 16 24 32 40 48 56 64 9 18 27 36 45 54 63 72 81 假设:行号为i ,列号为j i=6 j=5 i*j (1<=j<=i) (1<=i<=9) 则:第 i行中要输出j个乘积 公共计算机基础教研部
4.5 循环的嵌套 <例>修改上例,实现如下三角形九九乘法表。 main() { int i, j; for(i=1; i<=9; i++) { for(j=1; j<=i; j++) printf(“%2d”, i*j); printf(“\n”); } } 公共计算机基础教研部
5.5 用break语句和continue语句 改变循环状态 5.5.1 用break语句提前退出循环 • break语句可以用来从循环体内跳出循环体,即提前结束循环,接着执行循环下面的语句 一般形式: break; 注意:break语句不能用于循环语句和switch语句之外的任何其他语句中。 公共计算机基础教研部
5.5 用break语句和continue语句 改变循环状态 程序的作用是计算r=1到r=10时的圆面积,直到面积area大于100为止。从上面的for循环可以看到:当area>100时,执行break语句,提前结束循环,即不再继续执行其余的几次循环。 例: float pi=3.14159; for(r=1;r<=10;r++) { area=pi*r*r; if(area>100) break; printf(″r=%f,area=%f\n″,r,area); } 公共计算机基础教研部
5.5 用break语句和continue语句 改变循环状态 break 语句 跳出while 循环 while(1) { if(x == 10) break; } 跳出for 循环 for( ; ; ) { printf("这将一直进行下去"); i = getchar(); if(i == 'X' || i == 'x') break; } 跳出do-while 循环 do { if (x == 10) break; }while (x< 15); 公共计算机基础教研部
5.5 用break语句和continue语句 改变循环状态 5.5.2 用continue语句提前结束本次循环 • continue语句作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定. 一般形式: continue; 公共计算机基础教研部
4.5.2 break与continue语句 continue 语句 while(…) { …… …… break; …… …… } while(…) { …… …… continue; …… …… } 继续下一次循环 跳出整个循环 break 语句 公共计算机基础教研部
break语句 功能:在循环语句和switch语句中,终止并跳出循环体或switch 说明: break只能终止并跳出最近一层的结构 break不能用于循环语句和switch语句之外的任何其它语句之中 5.5 用break语句和continue语句 改变循环状态 • continue语句 • 功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断 • 仅用于循环语句中 公共计算机基础教研部
5.5 用break语句和continue语句 改变循环状态 <例> 分析程序功能。 <即> 把100~200之间的不能被3整除的数输出 main() { int n; for(n=100;n<=200;n++) { if(n%3= =0) break; printf("%d ",n); } } main() { int n; for(n=100;n<=200;n++) { if(n%3= =0) continue; printf("%d ",n); } } 100 101 103 104 106 107 …… 200 100 101 公共计算机基础教研部
5.5 用break语句和continue语句 改变循环状态 <例>:求555555的约数中最大的三位数是多少? main( ) { int j; long n=555555; /*所求的约数的可能取值是从999到100,j从大到小*/ for (j=999; j>=100; j--) if ( n%j==0 ) /* 若能够整除j,则j是约数 */ { printf(”3 digits in %ld=%d\n”, n, j ); break; /* 控制退出循环 */ } } 公共计算机基础教研部
<例>:判断输入的整数是否是素数 算法 使用穷举法,从2开始尝试能否整除整数m。 5.7 程序举例 main() { int m,i; scanf(“%d”,&m); for(i=2;i<m;i++) if( m % i = = 0) break; if(i < m) printf(“%d is not a prinme number.\n”,m); else printf(“%d is a prinme number.\n”,m); } 对于穷举法来说,为了提高程序的效率,就要减少尝试次数。 i<m/2 i<sqrt(m) 公共计算机基础教研部
5.7 程序举例 # include <math.h>main( ){ int m,k,i,n=0; for(m=101;m<=200;m=m+2) { k=sqrt(m); for (i=2;i<=k;i++) if (m%i==0) break; if (i>=k+1) { printf("%d ″,m); n=n+1; } if(n%10==0) printf(″\n″); }} <例>:求100~200间的全部素数。 运行结果: 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 公共计算机基础教研部
ABCDEFGHIJKLMNOPQRSTUVWXYZ 5.7 程序举例 <例> 译密码。为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。 例如 Hello,world! 译成密码:Lipps,asvph! 将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变成B,Y变成C,Z变成D。 公共计算机基础教研部
5.7 程序举例 #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); } } 公共计算机基础教研部
<例>:百钱百鸡问题 中国古代数学家张丘建在他的《算经》中提出了著名的“百钱百鸡问题”: 鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,翁、母、雏各几何? 问题分析与算法设计 设:要买x只公鸡,y只母鸡,z只小鸡,可得到方程: x + y + z = 100 ① 5 x + 3 y + z / 3 = 100 ② 取值范围:0 <= x、y、z <= 100 可以采用穷举法求解。 公共计算机基础教研部
main( ) { int x,y,z,j=0; for(x=0;x<=20;x++) for(y=0;y<=33;y++) for(z=0;z<=100;z++) if(x+y+z==100 && 5*x+3*y+z/3==100 ) printf("%2d:cock=%2d hen=%2d chicken=%2d\n", ++j,x,y,z); } 运行结果: 1: cock= 0 hen=25 chicken=75 2: cock= 3 hen=20 chicken=77 ……………… 7: cock=12 hen= 4 chicken=84 公共计算机基础教研部
丢失重要条件:z应该能够被3整除。 main( ) { int x,y,z,j=0; for(x=0;x<=20;x++) for(y=0;y<=33;y++) for(z=0;z<=100;z++) if(z%3==0&&x+y+z==100&&5*x+3*y+z/3==100 ) printf("%2d:cock=%2d hen=%2d chicken=%2d\n", ++j,x,y,z); } 运行程序,正确的结果: 1: cock= 0 hen=25 chicken=75 2: cock= 4 hen=18 chicken=78 3: cock= 8 hen=11 chicken=81 4: cock=12 hen= 4 chicken=84 公共计算机基础教研部
<例>:如何判断一个整数是另一个整数的平方 从键盘上任意输入一个正整数,要求判断该正整数是否是另一个整数的平方。 问题分析与算法设计 设:输入的正整数为i,若i满足: i = = m*m (m为整数>0) 则i为整数m的平方。 main( ) { int i, m; scanf(“%d”, &i); for( m=1; m*m<i; m++) ; if( i==m*m) printf(“%d*%d=%d\n”, i, i, m); } 公共计算机基础教研部
<例>:抓交通肇事犯 一辆卡车违犯交通规则,撞人后逃跑。现场有三人目击事件,但都没有记住车号,只记下车号的一些特征: 甲说:牌照的前两位数字是相同的; 乙说:牌照的后两位数字是相同的,但与前两位不同; 丙是位数学家,说:四位的车号刚好是一个整数的平方。 请根据以上线索求出车号。 问题分析与算法设计 按照题目的要求造出一个前两位数(i)相同、后两位数(j)相同且相互间又不同的整数。得到: (1)0<i<=90<=j<=9 (2)i!=j (3)1100 * i + 11 * j = m*m (m为整数>=31) 公共计算机基础教研部
main( ) { int i,j,k,m; for(i=1;i<=9;i++) /* i:车号前二位的取值 */ for(j=0;j<=9;j++) /* j:车号后二位的取值 */ if(i!=j) /* 判断两位数字是否相异 */ { k=i*1000+i*100+j*10+j; for(m=31;m*m<k;m++) ; if(m*m==k) /* 判断是否为整数的平方 */ printf("Lorry_No. is %d.\n", k); } } 运行结果:Lorry_No. is 7744. 公共计算机基础教研部
编程练习 打印输出如下图形: A AA AAA AAAA AAAAA 打印输出如下图形: A BB CCC DDDD DDDDD 打印输出如下图形: A BBB CCCCC DDDDDDD EEEEEEEEE 公共计算机基础教研部