460 likes | 609 Views
第五章 循环结构程序设计. 第五章 循环结构程序设计. 第一节 循环的基本概念 第二节 while 语句 第三节 do -while 语句 第四节 for 语句 第五节 几种循环的比较 第六节 循环的嵌套 第七节 break 和 continue 语句 第八节 应用实例. 问题1:. §5.1 循环的概念. 一、循环问题. 什么是循环? 为什么要使用循环?. . 求1+2+3+ … +100的和。. 问题2: 求学生平均成绩。 ( 分数相加后除以课数 ).
E N D
第五章 循环结构程序设计
第五章 循环结构程序设计 第一节 循环的基本概念 第二节 while语句 第三节 do -while语句 第四节 for语句 第五节 几种循环的比较 第六节 循环的嵌套 第七节 break和continue语句 第八节 应用实例
问题1: §5.1 循环的概念 一、循环问题 什么是循环? 为什么要使用循环? 求1+2+3+…+100的和。 问题2:求学生平均成绩。(分数相加后除以课数) 问题3:找出整数[1~1000]中能同时被3和7整除的数。 循环是有规律的重复操作。将复杂问题分解为简单的操作过程,程序只对简单过程描述,这些过程的多次重复就可完成对问题的求解。 • if--goto 循环 • while循环 • for循环 • do while循环 先判断后循环 (当型循环) 先循环后判断 (直到型循环)
循环体 Y 条件 N N 条件 Y 循环体 §5.1 循环的概念(完) 循环的基本要素 循环变量的初值 • 循环变量的初始值 • 循环进入条件 • 循环体 • 循环变量的增值 满足条件则执行循环体 重复执行的语句 循环变量的改变,进一步测试条件 区别? 入口 二、循环结构 出口 先循环后判断 先判断后循环
§ 5.2 无条件转向语句 标号由数字,字母,下划线组成 一、goto语句(无条件转向语句) 格式:goto 标号标识符 功能:执行该语句时,将程序流程无条件地转向指定标号所在的语句继续执行。 goto loop; 二、标号语句 格式:标号标识符:语句 功能:指示语句在程序中的位置,作为转移语句的转移目标 loop: if(x<=y) scanf(“%d,%d”,&x,&y); loop:if(x<=y) { t=x;x=y;y=t;} goto loop; ……
§ 5.2 无条件转向语句 main( ) { int k, sum=0; k=1; loop: if(k<=100) { sum=sum+k; k++; goto loop; } printf(“%d”,sum); } goto 说明:goto可以从较深的多重循环中转移到外层,或从函数内,转移到函数外,不能从外到内 冒号
§5.2 用while设计循环结构 条件 while循环 while (条件) {语句组} 1. 格式:while(表达式) 循环体 2. 功能:先判断表达式的值,若为非零,重复执行循环体语句,再判断…直到表达式的值为零,退出循环体。 main ( ) { int s,n ; s=0 ; n=1; while(n<=100) { s=s+n ; n++; } printf(“%d\n”, s); } 即:测试---执行--测试--执行-- 100
§5.2 用while设计循环结构(续) 3.说明: (1)当循环体中语句多于一条时,用{ },否则,循环只对一个;起作用. (2)循环体内部必须有实现对循环变量增值的语句,否则,易出现“死循环”. (3) 条件表达式要有括号,后面不加分号. (4) 注意条件的边界值. 例题:求 1+2+3…+n<=10000的最大的n。 main( ) { int a,k; a=k=0; while(a<=10000) {++k; a+=k; } printf(“1+2+3…..+%d=%d\n”,k-1,a-k); }
§5.2 用while设计循环结构(续) number初值为 0, 条件为number<=1 main( ) { int number=0; while(number<=1) { number++; printf(“%d\n”,number); } } 1.number为0,满足条件 number为0,然后自增为1 输出number 1 2.number为1,满足条件 number为1,然后自增为2 输出number 2 结果: 1 2 3.number为2,不满足条件
§5.2 用while设计循环结构(续) main( ) { int number=0; while(number++<=1) printf(“*%d\n”,number); printf(“**%d\n”,number); } 循环进行了多少次? 输出的值? @ # 输出的number的值 1 2 3 条件表达式执行次数 1 2 3 条件表达式中变量的值 0 1 2 执行哪个printf语句 @ @ # 结果 : *1 *2 **3
循环体 Y 条件 N §5.3 用do-while设计循环结构 条件 do -while循环 1. 格式:do 循环体 while(表达式); 2. 功能:先执行循环体,再判断表达式的值,若为非零,重复执行循环体语句,再判断…….直到表达式的值为零,退出循环体 即:执行--测试---执行--测试-- do 语句 while (条件);
开始 初始化n,s 输入x s=s+n 结束 n++ 输出s n<=x N Y §5.3 用do-while设计循环结构(续) main() { int n=1,s=0,x; scanf("%d",&x); do {s=s+n; n++;} while (n<=x); printf("s=%d\n",s); } 条件表达式后有分号
§5.3 用do-while设计循环结构(完) 3、 while与do while的比较 main() {int s=0,x; scanf("%d",&x); do {s=s+x; x++;} while(x<=10); printf("s=%d\n",s); } 输入:12 输出: s=12 main() {int s=0,x; scanf("%d",&x); while (x<=10) {s=s+x; x++;} printf("s=%d\n",s); } 输入:12 输出: s=0 循环至少 执行一次 循环没有 被执行
§5.4 用for语句设计循环结构 for语句 初值表达式1 条件表达式2 增量表达式3 1. 格式 : for (表达式1;表达式2;表达式3) { 语句组 } 2. 功能 : 计算表达式1初值; 计算表达式2并判断,0 时跳出循环,非0 时执行循环; 当表达式2非0,执行循环体语句,计算表达式3增量; 自动转到第二步(计算表达式2)…...继续执行。 变量的增量 main( ) { int n, s; for(n=1 ; n<=100 ;n++) s=s+n; printf(“%d\n”,s); } 变量的初值 循环条件 循环体
不可用 §5.4 用for语句设计循环结构(续) 3.说明 1.表达式1,表达式2和表达式3均可缺省 分号始终不能缺省! for (;n<100;n++) 缺省e1, n 应在循环之前赋初值 for (n=0;;n++) 缺省e2, 造成死循环,不可使用! for (n=0;n<100;) 缺省e3, n增量应在循环体内进行 for (; ;) 缺省e1,e2,e3 死循环 for (;n<100;) 缺省e1,e3
§5.4 用for语句设计循环结构(续) 2.表达式1和表达式3可是与初值、增量无关的逗号表达式 for (s=0,n=1;n<=100;s=s+n, printf(“ %d” ,s)) n++; for (s=0;n<100;s=s+n,n++) {printf(“ %d” ,s);} 增量在for 之外完成 求累加和 n的初值在 for之前完成 for(初值;判断;增量) 语句; for(初值;判断;增量) {复合语句;} for(初值;判断;增量); for语句的形式:
开始 初始化n,s,x 输入x N n<=x Y s=s+n 输出s n++ 结束 §5.4 用for语句设计循环结构(续) for(;n<=x;) if-goto While(n<=x) main() { int n=1,s=0,x; scanf("%d",&x); loop:if(n<=x) {s=s+n; n++; gotoloop;} printf("s=%d\n",s); } 10 s=55 100 s=5050 255 s=32640 while(n<=x) for(;n<=x;) 循环结束 } }
无循环体 循环体 §5.4 用for语句设计循环结构(完) 输出结果: n=1 n=3 n=5 n=7 n=9 特点:先判断后循环 以下程序的输出结果 main() { int n,s; for(n=1;n<=10;n+=2) printf("n=%d\n",n); } main() { int n,s; for(n=1;n<=10;n+=2); printf("n=%d\n",n); } 输出结果: n=11 ; printf("n=%d\n",n);
§5.5几种循环的比较 1 、C中的三种循环语句while( ) ,do-while( ), for( ) 都可由表达式控制重复执行一个循环体,都可以用来解决同一个问题,一般情况下,可以相互代替。 2 、三种循环各有特点: 1) 当循环次数及条件在程序运行中才能确定时,选用while( )或do-while( )语句 两者区别:while( )顶部测试,可能一次也不执行 do-while( )底部测试,至少执行一次
§5.5 几种循环的比较(完) (2) 如果初值,条件明显,循环次数已给出,选用for( )语句,功能最强。 main() { int I=0,j=5; while(j<10) { j=I*2; printf(“%d”,j); } 结果为: ? (3) 出现“死循环”的几种情况 for( ; ; ) for( ….; 非零常数表达式;……) while(非零常数表达式) do ..while(非零常数表达式)
§5.6循环的嵌套 • 在循环体中,又包含有循环结构。 一、循环嵌套的概念 1 2 3 4 5 6 7 8 9 --------------------------------- 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 行循环中包含了列循环。 双重循环 将一元钱换成硬币,共有多少种换法?
§5.6循环的嵌套(续) 二、嵌套结构规则 内循环 外循环 入口 交叉循环 内循环出口 外循环出口 外循环 内循环出口 三、循环嵌套的运行过程 外层循环取一个值,内层循环取遍所有的值
§5.6循环的嵌套(续) 例: 每只公鸡5个钱,每只母鸡3个钱,每3只小鸡1个钱,用100个钱,买100只鸡,问公鸡、母鸡和小鸡各买几只? 定义变量x,y,z ,表示公鸡、母鸡和小鸡的只数 int x,y,z; for(x=1;x<=20;x++) for(y=1;y<=33;y++) for(z=1;z<=300;z++) { ….} 程序运算多少次? 分 析
§5.6循环的嵌套(续) x最多为20,y最多为33,当x,y已确定时,z的值为100-x-y 所求的z不能被3整除如何解决? 共六组解: x y z 3 20 77 4 18 78 7 13 80 8 11 81 11 6 83 12 4 84 main() { int x,y,z; for(x=1;x<20;x++) for(y=1;y<=33;y++) { z=100-x-y; if(5*x+3*y+z/3==100) printf(“%d,%d,%d\n”,x,y,z); } }
§5.6循环的嵌套(续) 将一元钱换成一分,二分和五分的硬币,共有多少种换法? main( ) { int a,b,c,k=0; for(a=0;a<=100;a++) for(b=0;b<=50;b++) for(c=0;c<=20;c++) { if (a+2*b+5*c==100) k++; } printf(“%d\n”,k); } 定义变量a,b,c 定义变量 k 计数器 循环体
§5.6循环的嵌套(续) • 要求:从键盘输入m值,输出m行每行m个*号。 例:输入m=4,输出的图形如下: • 思路: • 1. 输入m; • 2. 重复打印m行,每行打印m个*; * * * * * * * * * * * * * * * * 1. 输入m; 2. for ( k=1; k<=m; k++) 打印一行中的 m 个* ;
§5.6循环的嵌套(完) • main ( ) • { int k, m, j; • scanf ( “%d”, &m); • for( k=1; k<=m; k++) • { for ( j=1; j<=m; j++) • printf (“*”); • printf(“\n”) ; } • } • 细化: 1. 输入m; 2. for ( k=1; k<=m; k++) { 打印 m 个* ; 换新行; } • 1. 输入m; 2. for ( k=1; k<=m; k++) { for ( j=1; j<=m; j++) printf (“*”); printf(“\n”) ; }
§5.7break和continue语句 break语句与continue语句 循环的退出 • break语句格式 break; • break语句的功能 1.在switch语句中结束case子句,使控制转到 switch语句之外。 2.在循环结构中,break语句使流程转向该循环体的外层继续运行。向外退出一层循环
§5.7break和continue语句(续) 例题:求100以下的整数中为13的倍数的最大数 main( ) { int i; for (i=100; i>=0; i--) { if((i%13)==0) break;} printf(“%d\n”,i); } 如何求100以下 所有13的倍数
§5.7break和continue语句(续) • continue语句格式: continue; 循环的退出 continue语句的功能: continue语句仅能在循环语句中使用。 它的作用不是结束循环,而是开始一次新的循环。结束一次循环 对于for语句,将控制转到执行增量和条件测试部分。 对于while和do-while语句,将控制转到条件测试部分。
§5.7break和continue语句(续) 将前面例题中,小鸡的数z中不能被3整除的解筛除? main( ) { int x,y,z; for(x=1;x<=20;x++) for(y=1;y<=33-x;y++) { z=100-x-y; if(5*x+3*y+z/3==100) {if(z%3!=0) continue; printf(“%d,%d,%d\n”,x,y,z); }} } 结束一次循环
§5.7break和continue语句(续) 1. i=0 main( ) { int i,j,a=0; for(i=0;i<2;i++) { for(j=0;j<4;j++) { if(j%2) break; a++;} a++; # } printf(“a=%d\n”,a); } j=0,if为0,a从0到1 j=1,if为1 退出 j循环 执行语句 # a从1到2 2. i=1 j=0,if为0,a从2到3 j=1,if为1 退出 j循环 执行语句# a从3到4 a=4 a=5 a=6 a=7 break的使用
§5.7break和continue语句(完) main( ) { int i,j,x=0; for(i=0;i<2;i++) { x++; for(j=0;j<=3;j++) { if(j%2) continue; x++;} x++; # } printf(“x=%d\n”,x); } 1. i=0, x从0到1 j=0,if 为0 ,x从1到2 j=1,if 为1 j=2,if为0,x从2到3 j=3,if为1 j=0,if 为0,x从5到6 j=1,if 为1 j=2,if为0 ,x从6到7 j=3,if为1 内部循环 执行 语句# x为4 x为8 2. i=1,x从4到5 x=4 x=8 x=6 x=12 continue的使用
§5.8循环应用 例题1 一个古典数学问题: 有一对兔子,从出生后第3个月起每月都生一对兔子。小兔子长到第三个月后每月又生一对兔子。假设所有兔子都不死,问每个月的兔子总数为多少只及四十个月后所有兔子的总数? 设以不满1个月的为小兔子,满1个月不 满2个月的为中兔子,3个月以上的为老 兔子,列出各个月的兔子情况:
§5.8循环应用 求Fibonacci数列的前40个数? F1=1 (n=1) F2=1 (n=2) Fn=Fn-1+Fn-2 (n>=3) 数列特点:第1,2两个数为1,1。从第三个数开始,该数是其前面 两个数之和。即:
§5.8循环应用(续) 2. 解题方法: 设计求每月兔子总数的通用程序。设计一个计数器i表示当前月数,变量f1,f2分别表示前两月兔子总数并分别输出,当计数器i值变为20时,能得出前四十个月所有兔子数(总数)。 3. 程序与流程图
开始 初始化f1,f2 初始化i N i<=20? Y 输出f1和f2 f1=f1+f2 f2=f1+f2 结束 §5.8循环应用(续) main( ) { long f1,f2; int i; f1=1; f2=1; for(i=1;i<=20;i++) { printf(“%12ld,%12ld”,f1,f2); if(i%2==0)printf(“\n”); f1=f1+f2; f2=f2+f1; } }
ABCDEFGHIJKLMNOPQRSTUVWXYZ §5.8循环应用 例题C5-10 译密码(输入一行字符,要求输出其相应的密码。) 1. 问题分析 为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。 规律:将字母A变成字母E,(a变成e),即变成其后的第四个字母,W变成A,X变成B,Y变成C,Z变成D。非字母字符不变(如“China!”变成“Glmre!”)
开始 定义c N c!=‘\n’? Y N c为字母? Y Y 结束 c=c+4 N c>‘Z’&&c <‘Z’+4||C>‘z’ Y c=c-26 输出c §5.8循环应用(续) #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); } } 小写字母都>‘Z’+4
§5.8循环应用(续) 例题:求两个数的最大公约数 辗转相除法 已知两个数M和N,假定M>N,则求M%N,若余数r 为0,则N即为是所求,若余数r不为0,用N除 r,再求 其余数……直到余数为0,则除数就是最大公约数。 求76 与 64的最大公约数 r=76%64 , r 的值为12 r不为0 76与64的最大公约数为4 r=64%12 , r 的值为4 r不为0 r=12%4 , r 的值为 0
§5.8循环应用(续) 程序:main( ) { int x,y,t,r; scanf(“%d,%d”,&x,&y); if(x<y) { t=x; x=y; y=t; } while(x%y) { r=x%y; x=y; y=r; } printf(“%d\n”,y); } 输入64,76 交换x,y 条件是:余数不为0 除数做被除数,余数做除数
第五章 总结 一 有关循环的概念(满足条件重复执行一组语句) 二 循环结构的表达方法:四种语句(if-goto,while( ) ,do -while( ), for( ) ) 三 边界条件的处理(自增,自减在循环条件中的使用) 四 循环嵌套和多重循环 五 break, continue 的作用和区别
第五章 习题 • 设有一下程序段:则执行后结果为( ) • int x=0,s=0; while(!x !=0) s+=++x; printf(“%d”,s); • A. 输出0 B. 输出1 C. 条件表达非法 D. 构成死循环 2. 下面程序段的运行结果是: ( ) x=y=0; while(x<15) y++, x+=++y; printf(“%d,%d”,y,x); A. 20, 7 B. 6, 12 C. 20, 8 D. 8, 20 3. 下面程序段的运行结果是( ) for(y=1;y<10;)y=((x=3*y,x+1),x-1); printf(“x=%d,y=%d”,x,y); A. x=27,y=27 B. x=12,y=13 C. x=15,y=14 D. x=y=27
第五章 习题 4. 下面程序的运行结果是 ( ) main( ) { int I, b, k=0; for( I=1; I<=5; I++) {b=I%2; while(b-- >=0) k++; } printf(“%d,%d”,k,b);} A. 3, -1 B. 8, -1 C. 3, 0 D. 8, -2 5. 有1020个西瓜,第一天卖一半多两个,以后每天卖剩 下的一半多两个,问第几天后能卖完?请填空。 main( ) { int day=0,x1=1020,x2; while( ____) {x2=______; x1=x2; day++;} printf( “day=%d\n”,day); }
第五章 习题 6. 等差数列的第一项a=2,公差d=3,下面程序的功能是在前n项和中,输出能被4整除的所有的和。请填空。 main( ) { int a=2, d=3, sum=0; do { sum+=a; a+=d; if(______) printf(“%d\n”,sum);} while(sum<=200); } 7. 下面程序的运行结果是___________。 main( ) { int i, x, y; i=x=y=0; do { ++i; if (i%2==0) {x=x+i; i++;} y=y+i++; } while(i<=7); printf(“x=%d,y=%d\”,x,y); }
第五章 习题 • 下面程序的运行结果是___________。 • main( ) • { int i, j; • for(i=0;i<=3;i++) • { for(j=0;j<=5;j++) • {if (i==0||j==0||i==3||j==5) printf(“*”); • else printf(“ ”); } • printf(“\n”); } • }