1 / 43

第 6 章 循环结构的程序设计

第 6 章 循环结构的程序设计. while 语句 do-while 语句 for 语句 其他控制语句 break, continue. 循环型程序设计. sum=1+2+…+100;. 问题:编程序求 1+2+ … +100 之和 分析: 1 、设一个变量 sum 存放和,并初始化为 0 ; 2 、设置变量 i, 让其从 1 ~ 100 ,将这 100 个数一个一个加到 sum 中,加 100 次,而且每次都做同样的操作: sum=sum+i ; i++; ( i 从 1 增加到 100 )

hisoki
Download Presentation

第 6 章 循环结构的程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第6章 循环结构的程序设计 • while 语句 • do-while 语句 • for 语句 • 其他控制语句break, continue

  2. 循环型程序设计 sum=1+2+…+100; 问题:编程序求1+2+…+100之和 分析: 1、设一个变量sum存放和,并初始化为0; 2、设置变量i, 让其从1~100,将这100个数一个一个加到sum中,加100次,而且每次都做同样的操作: sum=sum+i;i++;(i从1增加到100) 3、当i增加到101时,停止计算;最后sum中的值就为所求的值 顺序结构和选择结构程序是每条语句最多执行一次,不能解决这个问题,因此要用到循环结构 循环结构是用于处理大量的有规律的重复操作 分析:sum=0 i=1 sum=sum+1=1 sum=sum+2=1+2=3 sum=sum+3=3+3=6 sum=sum+4=6+4=10 …… sum=sum+100=4950+100=5050

  3. 当P为真 A 假 P 真 A A A 直到P为假 真 P 假 6.1 概述(p103) • 循环结构: • 特点:在给定条件成立时,反复执行某程序段(循环体语句),直到条件不成立时,结束循环,继续执行循环体下面的语句 • 当型循环结构 while • 直到型循环结构 do while 注:A可以是一个简单语句,也可以是一个复合语句

  4. C语言可实现循环结构的语句: while 语句 do ~ while 语句 for 语句 6.1 概述(p106)

  5. while 假(0) 表达式 真(非0) 循环体 6.3 while语句 • 一般形式: while (表达式) 循环体语句 • 特点:先判断表达式,后执行循环体(当型) 此处无分号 ; • 执行流程:当表达式为真(非0值)时,执行while语句中的内嵌语句。 sum=0; i=1; while(i<=100) { sum=sum+i; i++; }

  6. 6.3 while语句 • 一般形式: while(表达式) 循环体语句 • 特点:先判断表达式,后执行循环体(当型) • 说明: • 循环体有可能一次也不执行(一开始条件就不成立) • 当表达式为真(非0值)时,即可继续执行循环 • 循环体包括一个以上语句的用{ }组成复合语句 • 有使循环趋向结束的语句,如 i++ • 无限循环: 也即无循环结束条件 while(1) 循环体; • 下列情况,退出while循环: • 条件表达式不成立(为零) • 循环体内遇 break,return,goto sum=0; i=1; while(i<=100) { sum=sum+i; i++; }

  7. 例6.2 用while循环求 循环条件 i=1 sum=0 当i<=100 sum=sum+i i++ 循环初值 输出sum 循环终值 循环变量增值 循环体 /*ch6-2.c*/ #include <stdio.h> void main() { int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } 循环结构的五要素:循环初值,循环条件,循环终值,循环变量增值,循环体

  8. 例6.2 用while循环求 /*ch6-2.c*/ #include <stdio.h> void main() { int i,sum=0,n; i=1; scanf(“%d”,&n); while(i<=n) { sum=sum+i; i++; } printf("%d",sum); } /*ch6-2.c*/ #include <stdio.h> void main() { int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } 求前n项的和 可用scanf读入n

  9. 例6-banjicj某班有10名学生,输入每个学生某门课程的成绩,并求出该班该门课程的平均分以及成绩为优秀(大于等于90分)的学生人数。 #include<stdio.h> void main() { int score,i=1,sum=0,count=0; printf("请输入学生10个成绩:\n"); while(i<=10) { scanf("%d",&score); sum=sum+score; if(score>=90) count=count+1; i=i+1; } printf("平均分为:%d\n",sum/10); printf("优秀人数为:%d\n",count); }

  10. do 循环体语句 循环体 while 当表达式值为真 真(非0) 表达式 N-S图表示 假(0) 6.4 do-while语句 • 一般形式: 此处有分号; do 循环体语句 while(表达式); • 执行流程:执行do-while语句中的内嵌语句,直到表达式为假(0)才跳出循环。

  11. 循环体 While循环 do 假(0) 表达式 真(非0) 循环体 循环体 while 真(非0) 表达式 假(0) • 特点:先执行循环体,后判断表达式(直到型) • 说明: • 至少执行一次循环体 • 循环体如果包含一个以上的语句,必须使用复合语句形式 • 在循环体中,必须有使循环条件趋向于不满足(假)的语句 • do-while可转化成while结构

  12. 例6.3 用do~while循环求 i=1 sum=0 sum=sum+i i++ 当i<=100 (直到i>100) 输出sum /*ch6-2.c*/ #include <stdio.h> void main() { int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } /*ch6-3.c*/ #include <stdio.h> void main() { int i,sum=0; i=1; do { sum+=i; i++; } while(i<=100); printf("%d",sum); } 此处有分号; 与while语句得出的结果一样

  13. 例6.4 while和do~while比较 /*ch6-4.c*/ #include <stdio.h> void main() { int i,sum=0; scanf("%d",&i); do { sum+=i; i++; }while(i<=10); printf("%d",sum); } /*ch6-4-1.c*/ #include <stdio.h> void main() { int i,sum=0; scanf("%d",&i); while(i<=10) { sum+=i; i++; } printf("%d",sum); } 结论:当 while后的表达式第一次的值为“真”时,两种结果相同,否则不同 输入:10 输出:sum=10 输出:sum=10 输入:11 输出:sum=11 输出:sum=0

  14. for 表达式1 假(0) 表达式2 真(非0) 循环体 表达式3 此处无分号; 6.5 for语句 • 一般形式: for (表达式1; 表达式2; 表达式3 ) 循环体语句 sum=0; for (i=1;i<=100;i++) sum=sum+i; 1.先求解表达式1; 2.求解表达式2,若其值为真(非0),则执行循环体的内容,然后执行第3步。若为假(0),则结束循环,执行for语句下面一条语句。 3.若表达式为真,执行指定的语句后,求解表达式3。 4.返回第2步执行。 5.循环结束,执行for语句下面的一个语句。 • 执行流程: sum=0; i=1; while(i<=100) { sum=sum+i; i++; }

  15. for (表达式1;表达式2;表达式3) • for语句一般应用形式: for( 循环变量赋初值;循环条件;循环变量增值) { 循环体语句 } • 说明: • for语句中表达式1、表达式2、表达式3类型任意,都可省略,但分号;不可省。如:for( ; ; ) #include <stdio.h> void main() { int i,sum=0; for(i=1;i<=100;i++) sum+=i; printf("%d",sum); }

  16. 例:#include<stdio.h> void main( ) { int i; for(i=0;i<10;i++) putchar(‘a’+i); } 例:#include<stdio.h> void main( ) { int i=0; for(;i<10;i++) putchar(‘a’+i); } 省略表达式 1 如何分析循环程序的运行结果? 将i值带入 运行结果:abcdefghij 例: #include<stdio.h> void main( ) { int i=0; for(;i<10;) putchar(‘a’+(i++)); } 例: #include<stdio.h> void main( ) { int i=0; for(;i<10;putchar(‘a’+i),i++) ; } 省略循环体 省略表达式1、3

  17. /*ch6-for-1.c*/ void main() { int i,j,k; for(i=0,j=100;i<=j;i++,j--) { k=i+j; printf("%d+%d=%d\n",i,j,k); } } 结论:for语句的功能强大 表达式 1、3为逗号表达式 此循环执行几次 i+j=0+100=100i+j=1+99=100i+j=2+98=100……i+j=50+50=100 /*ch6-for-2.c*/ #include<stdio.h> void main() { char c; for(;(c=getchar())!='\n';) printf("%c ",c); } /*ch6-for-3.c*/ #include <stdio.h> void main() { int i,c; for(i=0;(c=getchar())!='\n';i+=3) printf("%c ",i+c); } 打印一串字符,遇回车结束 输入:abc  输出:a e i

  18. 6.7 几种循环的比较 1、三种循环语句在处理循环问题时,一般可以相互替代 2、对于循环次数不确定的问题,可以用while或do-while语句来实现。 while语句为先判断后执行,do-while语句则先执行后判断。 3、对于循环次数确定的问题,用for语句更方便。for语句也为先判断后执行。

  19. 三种循环结构:求1~100的和 sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); sum=0; i=1; do { sum+=i; i++; } while(i<=100); printf("%d",sum); sum=0; for(i=1; i<=100; i++) sum+=i; printf("%d",sum);

  20. 6.8.1 break语句 一般形式:break; 功能:放在循环语句和switch语句中,用于终止并跳出循环体或开关体(switch语句),接着执行循环语句(或switch语句)后面的语句。 说明: break只能终止并跳出最近一层的循环(嵌套循环时)。如果要跳出多层循环,需用goto语句 break不能用于循环语句和switch语句之外的任何其它语句之中 6.8 break语句和continue语句(p122) for(i=1; i<=100; i++) { if(i>50) break; sum+=i; } printf("%d",sum);

  21. while do 假(0) 表达式 …… break; …... 真(非0) …… break; …… 循环体 循环体 while 真(非0) 表达式 假(0)

  22. for 表达式1 switch 假(0) 表达式2 表达式 真(非0) case …… break; …... const 1 const 2 const n default 语句组1 break; 语句组2 break; 语句组n break; 语句组 break; …... 表达式3 循环体

  23. 例1 break举例:按不同的半径,输出圆面积,面积大于100时停止 #include <stdio.h> #define PI 3.14159 void main() { int r; float area; for(r=1;r<=10;r++) { area=PI*r*r; if(area>100) break; printf("r=%d,area=%.2f\n",r,area); } } 运行lt6-area.c 通常break语句总是和if语句连在一起 if(area<=100) printf("r=%d,area=%.2f\n",r,area); else break;

  24. 运行 lt6-14.c , lt6-14-1.c • 例2 break举例: • 小写字母转换成大写字母,直至输入非小写字母字符。 #include <stdio.h> void main() { char c; while(1) { c=getchar(); if(c>='a' && c<='z') putchar(c-'a'+'A'); else break; } putchar(‘\n’); } #include <stdio.h> void main() { char c; while(1) { c=getchar(); if(c>='a' && c<='z') putchar(c-'a'+'A'); else if(c>=‘A' && c<=‘Z') putchar(c); elsebreak; } putchar(‘\n’); } 只将小写字母转成大写字母输出 将小写字母转成大写字母输出如果是大写字母,则直接输出

  25. 例6.5 输出1到100之间能被9整除的数 #include<stdio.h> void main() { int i; for(i=1; i<=100; i++) { if(i%9!=0) continue; printf("%d\n",i); } } • 6.8.2 continue语句 • 一般形式:continue; • 功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断,如果条件成立,继续执行循环。 • 说明: • 仅用于循环语句中 • continue 语句仅结束本次循环,但break语句则是结束整个循环过程。 运行 lt6-5.c

  26. for 表达式1 while do 假(0) 表达式2 假(0) 表达式 真(非0) …… continue; …... 真(非0) …… continue; …... …… continue; …… while 真(非0) 表达式 表达式3 假(0)

  27. 例3 求输入的十个整数中正整数的个数及其和与平均值 运行lt6-15.c 分析:i为循环变量,从1~10 十个整数n, 用scanf读入 正数的个数放入num中 正数的和放入sum中 正数的平均值为aver= sum/num #include <stdio.h> void main() { int i, n, num=0; float sum=0,aver; for(i=0;i<10;i++) { scanf("%d",&n); if(n<=0) continue; num++; sum=sum+n; } aver=sum/num; printf("%d plus integer's sum :%.2f\n",num,sum); printf("Mean value:%.2f\n",aver); } if(n>0) { num++; sum+=n; } else continue; if(n>0) { num++; sum+=n; } 行不? for循环中scanf的输入格式要用空格或回车 注意:scanf的输入格式是用12 45 69还是用12,45,69

  28. break语句与continue语句的比较 结束整个循环 while (表达式1) {… if (表达式2) break; … } 格式 while (表达式1) {… if (表达式2) conitue; … } 结束本次循环 … ... sum=0; for (i=1;i<=8;i++) { if (i==5) continue; sum=sum+i; } printf(“sum=%5d\n”,sum); … ... … ... sum=0; for (i=1;i<=8;i++) { if (i==5) break; sum=sum+i; } printf(“sum=%5d\n”,sum); … ... 举例 sum=1+2+3+4=10 sum=1+2+3+4+6+7+8=31

  29. 外循环 内循环 内循环 6.6 循环的嵌套 • 三种循环可互相嵌套,层数不限 • 外层循环可包含两个以上内循环,但不能相互交叉 • 嵌套循环的执行流程 (1) while() { …… while() { …… } …... } (3) while() { …… do { …… }while( ); ……. } (2) do { …… do { …… }while( ); …... }while( ); (4) for( ; ;) { …… do { …… }while(); …… while() { …… } …... } • 嵌套循环的跳转 禁止: • 从外层跳入内层 • 跳入同层的另一循环 • 向上跳转

  30. 6-pingguo:现有100个苹果,决定将所有的苹果进行装盒出售。 现有大、小两种盒子,要求如下: 包装规格分别是:小盒每盒可装8个、大盒每盒可装12个,并且大小盒子都要用到。 输出所有可能的包装方案。 #include<stdio.h> void main() { int x,y; printf("小盒数 大盒数\n"); for(x=1;x<12;x++) for(y=1;y<8;y++) if(x*8+y*12==100) printf("%-8d%-8d\n",x,y); }

  31. 例 2:根据输入的边长,输出正方形 运行lt66.c #include<stdio.h> void main() { int i,j,n; printf("input n: "); scanf("%d",&n); while(n>0&&n<=20) { for(i=1;i<=n;i++) { for (j=1;j<=n;j++) printf(“ * "); printf("\n"); } printf("input n: "); scanf("%d",&n); } }

  32. 9 1 3 2 1 4 6 2 18 2 3 9 6 27 3 12 36 8 4 4 5 5 10 15 45 6 6 18 54 12 7 7 21 63 14 72 16 24 8 8 9 9 18 81 27 j j i i …………….. 例 3 循环嵌套,输出九九表 #include <stdio.h> main() { int i,j; for(i=1;i<10;i++) printf("%4d",i); printf("\n-----------------------------------\n"); for(i=1;i<10;i++) for(j=1;j<10;j++) printf((j==9)?"%4d\n":"%4d",i*j); } 变量 i 控制行,变量 j 控制列 i=1, j 从1~9循环,输出 i*j i=2, j 从1~9循环, 输出 i*j for(i=1;i<10;i++) { for(j=1;j<10;j++) printf("%4d",i*j); printf(“\n”);}

  33. 1 9 18 2 27 3 36 4 45 5 6 54 7 63 72 8 9 81 j i 1 2 4 3 6 9 …………….. 例3 循环嵌套,输出九九表 运行lt6-99b.c /*ch6-ff.c*/ #include <stdio.h> void main() { int i,j; for(i=1;i<10;i++) printf("%4d",i); printf("\n-----------------------------------\n"); for(i=1;i<10;i++) for(j=1;j<=i;j++) printf((j==i)?"%4d\n":"%4d",i*j); } 变量 i 控制行,变量 j 控制列 i=1, j 从 1~i 循环,输出 i*j i=2, j 从 1~i 循环, 输出 i*j for(i=1;i<10;i++) { for(j=1;j<i;j++) printf("%4d",i*j); printf(“\n”);}

  34. for(i=1;i<10;i++) for(j=1;j<10;j++) printf((j==9)?"%4d\n":"%4d",i*j); i=1 假(0) i<10 真(非0) j=1 外循环 假(0) j<=10 真(非0) 内循环 printf j++ i++

  35. 例 6.6 用 公式求π的近似值,直到最后一项的绝对值小于10-6为止 … t=1,pi=0,n=1.0,s=1 当|t|>=1e-6 pi=pi+t n=n+2 s=-s t=s/n pi=pi*4 输出pi 6.9 程序举例 运行lt6-6.c /*ch6-6.c*/ #include <stdio.h> #include <math.h> void main() { int s; float n,t,pi; t=1; s=0; n=1.0; m=1; while((fabs(t))>=1e-6) { s=s+t; n=n+2; m=-m; t=m/n; } pi=s*4; printf("pi=%8.6f\n",pi); } 分析 分子:1,-1, 1,-1… s or -s 分母:1, 3, 5, 7… n+2

  36. 程序举例 运行lt6-8-1.c 判断m是否为素数。 例 6-8 素数(质数): 只能被1和它本身整除的数。 #include <stdio.h> #include <math.h> void main() { int m,i,k; scanf("%d",&m); k= m-1; for(i=2;i<=k;i++) if(m%i==0) break; if(i>k) printf("%d is ",m); else printf("%d is not ",m); printf("a prime number\n"); } 判别方法: 若数7不能被2~6之间的每一个数整除,则7为素数,否则7不是素数 设一个数为m, k=m-1, i=2~k : 如果m=7, 则k=m-1=6 , i=2~6 若m不能被每一个 i 的值整除 ,则m为素数,否则m不是素数。 flag=1; k=m-1; for (i=2;i<=k;i++) if (m%i==0) flag=0; if (flag==1) printf(“%d is a prime number\n”,m); else printf(“%d is not a prime number\n”,m); k=m-1; for (i=2;i<=k;i++) if (m%i==0) break; if (i>=k+1) printf(“yes!”); else printf(“no!”);

  37. 读入m k=m i=2 当i≤k m被i整除 假 真 用break 结束循环 i=i+1 i≥k+1 假 真 输出:m“不是素数” 输出:m“是素数” 运行lt6-8-2.c 例 6.8 判断m是否素数 k=m-1; k=[m/2]; [(m+1)/2]; k=[sqrt(m)]; [sqrt(m+1)] /*ch6-8.c*/ #include <stdio.h> #include <math.h> void main() { int m,i,k; scanf("%d",&m); k=sqrt(m); for(i=2;i<=k;i++) if(m%i==0) break; if(i>=k+1) printf("%d is ",m); else printf("%d is not ",m); printf("a prime number\n"); } 例6.9 求100~200间的全部素数

  38. 1 8 55 377 2584 17711 121393 832040 5702887 39088169 1 5 34 233 1597 10946 75025 514229 3524578 24157817 2 13 89 610 4181 28657 196418 1346269 9227465 63245986 3 21 144 987 6765 46368 317811 2178309 14930352 102334155 例6.7 求Fibonacci数列:1,1,2,3,5,8,……的前40个数。 F1=1 (n=1) F2=1 (n=2) Fn=Fn-1+Fn-2 (n≥3)

  39. 例6.7 求Fibonacci数列:1,1,2,3,5,8,……的前40个数。 F1=1 (n=1) F2=1 (n=2) Fn=Fn-1+Fn-2 (n≥3) 特点:第1、2个数为1、1。从第三个数开始,该数是其前面两个数之和。 F1=1 (n=1) F2=2 (n=2) Fn=Fn-1+Fn-2 (n>=3) 分析: 第 1 项: f1=1 第 2 项: f2=1 第 3 项: f3=f1+f2 第 4 项: f4=f2+f3 第 5 项: f5=f3+f4 第 6 项: f6=f4+f5 …… 第39项: f39=f37+f38 第40项: f40=f38+f39 f1= f1 + f2 f2= f2 + f1

  40. f1=1, f2=1 i=1 while( i<=20 ) 输出f1,f2 1 5 34 233 1597 10946 75025 514229 3524578 24157817 1 8 55 377 2584 17711 121393 832040 5702887 39088169 2 13 89 610 4181 28657 196418 1346269 9227465 63245986 3 21 144 987 6765 46368 317811 2178309 14930352 102334155 f1=f1+f2 f2=f2+f1 i++ 例6.7 求Fibonacci数列:1,1,2,3,5,8,……的前40个数。 #include <stdio.h> void main() { long int f1,f2; int i; f1=1; f2=1; i=1; while( i<=20) { printf("%15ld %15ld ",f1,f2); if(i%2==0) printf("\n"); f1=f1+f2; f2=f2+f1; i++; } }

  41. f1=1, f2=1 for i=1 to 20 输出f1,f2 f1=f1+f2 f2=f2+f1 例6.7 求Fibonacci数列:1,1,2,3,5,8,……的前40个数。 F1=1 (n=1) F2=1 (n=2) Fn=Fn-1+Fn-2 (n≥3) 运行lt6-7.c /*ch6-7.c*/ #include <stdio.h> void main() { long int 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; } }

  42. ABCDEFGHIJKLMNOPQRSTUVWXYZ 运行lt6-10.c 例6-10 译密码 /*ch6-10.c*/ #include <stdio.h> void 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); } } 例如: Hello,world! 译成密码:Lipps,asvph!

  43. 第六章补充习题 题6-money:现有50元纸币,要求换1元、5元和10元的纸币若干,并且每种纸币的个数不能为0。 编写程序要求: 输出所有可能的换币方案。假设换1元纸币个数为x,5元纸币个数为y,10元纸币个数为z。

More Related