1 / 50

第六章 循环控制

第六章 循环控制. §6.1 概述. 前面已介绍了顺序结构 , 选择结构,本章介绍循环结构 。. 实际问题 : 一组重复执行的语句。. sum=1+2+3+…+100;. 如 :.  则用循环结构解决。. C 语言用四种形式循环. 1. if 语句与 goto 语句. 2. while 语句. 3. do …while 语句. 4. for 语句. §6.2 goto 语句及与 if 语句构成循环. 1. goto 语句. 形式 : goto 标号;. 功能 : 无条件转向标号处。. 标号 :用标识符命名。. 2. 与 if 构成循环.

doris
Download Presentation

第六章 循环控制

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.1 概述 前面已介绍了顺序结构,选择结构,本章介绍循环结构。 实际问题:一组重复执行的语句。 sum=1+2+3+…+100; 如:

  2. 则用循环结构解决。 C语言用四种形式循环 1.if语句与goto语句 2.while 语句 3.do …while 语句 4.for语句

  3. §6.2 goto语句及与if语句构成循环 1. goto语句 形式: goto 标号; 功能: 无条件转向标号处。 标号:用标识符命名。 2. 与if构成循环. 例6.1: 求

  4. main ( ) { int i, sum=0; i=1; loop:if (i<=100) { sum=sum+i; i++; goto loop;} printf("%d", sum); } 运行结果如下: 5050

  5. §6.3 while语句 为了使程序的结构化功能强,应尽量少用goto语句。 专门的当型循环语句––while语句 1. 形式: while (表达式)语句 2. 执行过程: 先判断表达式的值。若0.则执行其后面的语句,否则while执行完毕。

  6. 表达式 =0 0 语句 下一语句 3.流程图: 将上述例子用while语句写出 例6.2 while (i<=100) { sum+ =i;//sum=sum+i i++; }

  7. 注: while后面的语句一般为复合语句, 即:加{ }  语句中应有使表达式=0的语句。 否则会出现无限循环–––"死"循环。

  8. 语句 0 表达式 =0 §6.4 do …while语句 一种专门的“ 直到型” 循环语句。 1. 形式: do语句while(表达式);注,其后有分号 2. 执行过程: 先执行语句,再判表达式的值,若0,再执行语句,否则结束循环 3. 流程:

  9. main ( ) { int i, sum=0; i=1; do { sum=sum+i; i++; } while (i<=100); printf("%d",sum); } 例6.3 while语句与do…while语句的区别: 当第一次执行时, 若表达式=0时,则while语句与do …while有所不同, do …while 执行一次后面的语句,而while不执行。 因此,do …while语句又叫做非0次循环语句。例P109 6.4

  10. §6.5 for语句 一种形式更为灵活的循环语句。 1. 形式 for(表达式1; 表达式2; 表达式3)语句 2.执行过程 首先计算表达式1,接着执行表达式2,若表达式2的值0,则执行语句,接着计算表达式3,再判断表达式2的值.依此重复下去,直到表达式2的值=0(假)。

  11. 计算表达式1 =0(假) 求表达式2值 0(真) 语句 计算表达式3 结束for语句 3.流程:

  12. 用for语句写出上述例子 for ( i=1; i<=100; i++) sum+=i; for语句完全可以用while代替,但for直观、简单、方便 for用while代替的流程 表达式1; while(表达式2) { 语句 表达式3; }

  13. 4. for语句的几种特例  可以省略表达式1, 但须保留分号;这时在for之前就得赋值给循环变量; 例: 任意输入两个整数a, b,求 main ( ) { int i, j, a, b, sum; printf ("please input two number!\n"); scanf ("a=%d, b=%d", &a, &b); i=a; j=b; if (a>b) {i=b; j=a;} for (; i<=j; i++) sum=sum+i; printf (" \n sum=%d", sum); }

  14. 表达式2一般不可省略,否则为无限循环 例: for (i=1; ; i++) sum=sum+i; 相当于条件永真、永不为0,若用while表示 相当于:while (1) { sum=sum+i; i++; }

  15. 表达式3亦可省略,但在循环体中须有语句修改循环变量;以使表达式2在某一时刻为0而正常结束循环。表达式3亦可省略,但在循环体中须有语句修改循环变量;以使表达式2在某一时刻为0而正常结束循环。 例: for (sum=0,i=1;i<=100;) { sum=sum+i; i++; }

  16. 若同时省略表达式1,表达式3,则相当于while(表达式2)语句。若同时省略表达式1,表达式3,则相当于while(表达式2)语句。 例: for (; i<=100;) {sum+=i; i++;} 相当于while (i<=100) { sum+=i; i++; }

  17. 三个表达式均省略 即for(;;)语句则相当于while(1)语句. 表达式1、表达式3可以是逗号表达式,以使循环变量值在修改时可以对其它变量赋值。 如for (sum=0,i=1;i<=100;i++,i++) 相当于:sum=0; for (i=1;i<=100;i=i+2)

  18. 表达式2可以是关系表达式,也可以是数值表达式或字符表达式。只要值0.即执行循环体.表达式2可以是关系表达式,也可以是数值表达式或字符表达式。只要值0.即执行循环体. 例:for (i=0; (c=getchar( ))!='\n'; i+=c);

  19. §6.6循环的嵌套 与其它语言一样,当循环体中又包含了另一个完整的循环语句时–––嵌套。 C有三种循环语句,均可以相互嵌套: while ( ) {… while ( ) {… } } for (; ;) { … while ( ) { } do { } while ( ); … } 均为正确的嵌套。

  20. while ( ) { … while ( ) { }… } for (; ; ) { for (; ; ) {… } } 会理解为正确的形式;但要注意语句的包含关系。

  21. §6.7几种循环的比较 • 对于同一问题, 四种循环可相互替代。但不提倡用goto. • for循环功能强于while, do…while.但若不是明显地给出循环变量初终值(或修改条件),则应用while 或do …while.以增强程序的结构化和可读性。 • 要防止无限循环——死循环。 • 循环过程中,为了结束本次循环或跳出整个循环。分别要用到continue和break语句。

  22. §6.8break语句和contiune语句 6.8.1 break语句 问题: 计算圆的面积r2, 半径取1, 2, 3, 4…,当面积>100时结束。 #define PI 3.14159 main() {… for(r=1; r<=10; r++) {area=PIrr; if (area>100) break;} printf ("%f", area); }

  23. 从结构化程序要求出发,用break,退出循环,进入for语句的下一条语句。从结构化程序要求出发,用break,退出循环,进入for语句的下一条语句。 注: break只能用于循环语句和switch语句。

  24. 6.8.2 continuce语句 问题: 编写程序,打印100~200中不能被3整除的数。 main( ) { int n; for (n=100; n<=200; n++) if (n%3!=0) printf("%d", n); }

  25. 换一种方式: main( ) { int n; for (n=100; n<=200; n++) {if (n%3==0) continue; printf ("%d", n); } } continue语句起了结束本次循环的作用。

  26. t=1,pi=0,n=1,s=1 当|t|>=10-6 pi=pi+t n=n+2 s=-s t=s/n pi=pi*4 输出pi §6.9程序举例 例6.6:用/4=1-1/3+1/5-1/7+…公式求的近似值,直到最后一项的绝对值小于10-6为止。 变量说明: s作分子,控制符号变化 n作分母,奇数序列 t=s/n,第i项值 pi先存放/4,再存放值

  27. 程序如下: #include <math.h> main() { int s;//做分子,取符号 float n,t,pi;//n做分母,t=s/n 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); }

  28. 例6.7:求Fibonacci数例: 1, 1, 2, 3, 5, 8, …前40个数。 规律:F1=1, F2=1 Fn=Fn – 1 + Fn – 2 (n>2) 程序要点:  f1=f1+f2; f2=f2+f1; 交替的结果正好为一序列  每输出4个数时换行。

  29. f1=1, f2=1 for i=1 to 20 输出f1, f2 f1=f1+f2 f2=f2+f1 程序如下: 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; } }

  30. 运行结果为: 1 5 34 233 1597 10946 75025 514229 3524578 24157817 1 8 55 377 2584 17711 1211393 832040 5702887 39088169 2 13 89 610 4181 28657 196418 1346269 9227465 63245986 3 21 144 987 6765 46368 317811 2178309 14930352 102334155

  31. 例6.9.求100~200的素数. 判一个数m是否为素数的方法: 的整数去除它时均不能除尽, 当用2, 3, … 则为素数。 每打印10个数,换一次行。

  32. 程序如下: #include <math.h> main() { int m, k, i, n=0; for (m=101; m<=200; m=m+2)//只判断奇数 { if ( n%10==0) printf("\n"); k=sqrt(m); for (i=2; i<=k;i++) if (m%i==0) break; if (i>=k+1) {printf("%d ",m); n=n+1;} } }

  33. 运行结果如下: 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199

  34. 例6.10:译密码。 规律:将输入的字母变成其后的第4个字母。 如,输入China! 译为Glmre! 程序要点:字符的ASCII码值+4; 若为WXYZ或wxyz之一,需转换为ABCD或abcd之一 if((c>=‘a’&&c<=‘z’)||(c>=‘A’&&c<=‘Z’)) {c=c+4; if(c>’Z’&&c<=’Z’+4||c>’z’) c=c-26; }

  35. 程序如下: #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); } }

  36. 循环控制应用 一、统计与计数问题 方法:计数变量c的初值为0,每输入一个数据,进行必要判断后,若输入的数据满足统计条件,则计数变量c自加1,这样当对所有输入进行判断后,计数变量c的值就是统计的结果。

  37. 例:输入若干非0实数,直到输入0时停止,要求输入的实数最多不超过20个,统计其中正数的个数,负数的个数。例:输入若干非0实数,直到输入0时停止,要求输入的实数最多不超过20个,统计其中正数的个数,负数的个数。 分析: 设三个计数变量: n-统计输入的数据总个数(为什么有必要?)posn-统计正数的数目negn-统计负数的数目

  38. #include<stdio.h> #include<math.h> void main() { int n,posn,negn;double a; n=0; posn=0; printf("Input real numbers:\n"); scanf("%lf",&a); while(fabs(a)>=1e-6&&n<20) { if(a>1e-6) posn++; n++; scanf("%lf",&a); } negn=n-posn; printf("posn=%d,negn=%d\n",posn,negn); }

  39. 二、数列求和/求积:累加/累乘/递推法 1.基本累加/累乘问题 累加法:求和变量初值一般为0,每循环一次,求和变量自加一个数据,这样循环结束后,求和变量的值即为这些数据的和。 累乘法:累乘变量初值一般为1,每循环一次,累乘变量自乘一个数据,这样当循环结束的时候,累乘变量的值即为这些数据连乘的积。

  40. 例:输入n个100分制成绩(用整型),计算并输出平均成绩,要求输出精确到两位小数。例:输入n个100分制成绩(用整型),计算并输出平均成绩,要求输出精确到两位小数。 #include <stdio.h>#define n 10void main() { double av=0; int score,i; printf(“Input %d int numbers:”,n); for(i=1;i<=n;i++) { scanf(“%d”,&score);av+=score; } av/=n; printf(“av=%.2f\n”,av);}

  41. 例: 输入n,m,计算组合数P=C(n,m) 。

  42. #include “stdio.h”void main(){ double p=1.0;int m,n,k; printf(“Input n,m:”); scanf(“%d%d”,&n,&m); if(n<0||m<0||m>n) { printf(“Input data aren’t correct.\n”); return; } if(n-m<m) m=n-m; /*这句有何作用?*/ for(k=1;k<=m;k++) p*=(double)(n-m+k)/k; /*此处为什么要强制类型转换?*/ printf(“c(%d,%d)=%.lf\n”, n,m,p);}

  43. 三、字符图形 例:*号图形 (打印行数n由键盘输入)

  44. 分析(2)号图形:从第1行打印到第n行,打印第i行时(i从1~n),首先打印n-i 个空格;接着打印 i个*号;换行; 分析:(6)号图形:打印第i行(i 从1~n)时,首先打印i-1个空格;接着打印2(n-i)+1个*号;换行;  

  45. #include “stdio.h”void main() { int n,i,j; printf(“Input n=“); scanf(“%d”,&n); for(i=1;i<=n;i++) { for(j=1;j<=n-i;j++) putchar(‘‘); for(j=1;j<=i;j++) putchar(‘*’); printf(“\n”); } } /*打印(2)号图形*/

  46. 例:“鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁母雏各几何?”(引自张邱建算经,公元五世纪)例:“鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁母雏各几何?”(引自张邱建算经,公元五世纪) 分析:设x,y,z分别表示鸡翁,鸡母,鸡雏的数目,则有 四、搜索(穷举求解) 上述方程属于不定方程,解并不唯一,因此,只能用搜索法对x,y,z的所有组合情况,测试满足条件的解。

  47. #include “stdio.h”void main(){ int x,y,z; printf(“ Cock Hen chicken\n”); for(x=0;x<=20;x++) for(y=0;y<=33;y++) { z=3*(100-5*x-3*y); if(z>=0&&x+y+z==100) printf(“%8d%8d%8d\n”,x,y,z); }}

  48. 例.输入两个自然数a,b,求它们的最大公约数与最小公倍数。例.输入两个自然数a,b,求它们的最大公约数与最小公倍数。 分析:设a,b的最大公约数为gcd(a,b),可用下式计算gcd(a,b),而最小公倍数=a*b/gcd(a,b)。 五、数论有关问题 例如:gcd(24,32) =gcd(32,24) =gcd(24,8) =gcd(8,0)=8

  49. #include “stdio.h”void main() /*两数求最大公约数与最小公倍数*/{ int a,b,t,m; printf(“Input a,b:”); scanf(“%d%d”,&a,&b); if(a<1||b<1) {printf(“Input isn’t correct.\n”); return; } m=a*b; while(b!=0) { t=a%b;a=b;b=t; } printf(“zdgys=%d,zxgbs=%d\n”,a,m/a);}

  50. 课外学习 • 看书(reading) p106——121 • 思考题(exercise) 6.3、6.5 • 作业题(problem) 6.7、6.11 • 上机题一(project) 6.2、6.4、6.8 • 上机题二(project) 6.1、6.6、6.14

More Related