520 likes | 683 Views
第六部分 循环控制. 第六章 循环控制. 0x1C. 0x18. 0x14. 0x10. 0x0C. 0x08. 0x04. 0x00. 提纲. goto. 1. while. 2. 3. do while. FIQ. IRQ. 4. (Reserved). for. Data Abort. Prefetch Abort. 5. 循环嵌套. Software Interrupt. Undefined Instruction. Reset. 概述 C 语言可实现循环的语句:
E N D
第六章 循环控制 0x1C 0x18 0x14 0x10 0x0C 0x08 0x04 0x00 提纲 goto 1 while 2 3 do while FIQ IRQ 4 (Reserved) for Data Abort Prefetch Abort 5 循环嵌套 Software Interrupt Undefined Instruction Reset
概述 C语言可实现循环的语句: 用goto 和 if 构成循环 while 语句 do ~ while 语句 for 语句 goto语句及用goto构成循环 goto语句一般格式: 6.1概述 • 标号:语句; • …….. • goto 语句标号; • ….…..
功能:无条件转移语句 • 说明: • 不能用整数作标号 • 只能出现在goto所在函数内,且唯一 • 只能加在可执行语句前面 • 限制使用goto语句
例用if 和goto语句构成循环,求 循环条件 循环初值 循环变量增值 循环终值 循环体 /*ch5_1.c*/ #include <stdio.h> main() { int i,sum=0; i=1; loop: if(i<=100) { sum+=i; i++; goto loop; } printf("%d",sum); } sum=0+1 sum=1+2=3 sum=3+3=6 sum=6+4 …… sum=4950+100=5050
例 从键盘输入一组数据,以0结束输入,求数据和 /*ch5_11.c*/ #include <stdio.h> main() { int number,sum=0; read_loop: scanf("%d",&number); if(!number) goto print_sum; sum+=number; goto read_loop; print_sum: printf("The total sum is %d\n",sum); }
while 假(0) expr 真(非0) 循环体 • while语句 • 一般形式: while(表达式) 循环体语句; • 执行流程:
特点:先判断表达式,后执行循环体 • 说明: • 循环体有可能一次也不执行 • 循环体可为任意类型语句 • 下列情况,退出while循环 • 条件表达式不成立(为零) • 循环体内遇break,return,goto • 无限循环: while(1) 循环体;
例 用while循环求 循环条件 循环初值 循环变量增值 循环终值 循环体 /*ch5_2.c*/ #include <stdio.h> main() { int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); }
例 显示1~10的平方 运行结果: 1*1=1 2*2=4 3*3=9 4*4=16 5*5=25 6*6=36 7*7=49 8*8=64 9*9=81 10*10=100 /*ch5_21.c*/ #include <stdio.h> main() { int i=1; while(i<=10) { printf("%d*%d=%d\n",i,i,i*i); i++; } }
do 循环体 while 真(非0) expr 假(0) • do~while语句 • 一般形式: do 循环体语句; while(表达式); • 执行流程:
循环体 While循环 假(0) expr 真(非0) 循环体 • 特点:先执行循环体,后判断表达式 • 说明: • 至少执行一次循环体 • do~while可转化成while结构
例 用do~while循环求 /*ch5_3.c*/ #include <stdio.h> main() { int i,sum=0; i=1; do { sum+=i; i++; }while(i<=100); printf("%d",sum); }
例 while和do~while比较 /*ch5_4.c*/ #include <stdio.h> main() { int i,sum=0; scanf("%d",&i); do { sum+=i; i++; }while(i<=10); printf("%d",sum); } main() { int i,sum=0; scanf("%d",&i); while(i<=10) { sum+=i; i++; } printf("%d",sum); }
for expr1 假(0) expr2 真(非0) 循环体 expr3 • for语句 一般形式: for([expr1] ;[ expr2] ;[ expr3]) 循环体语句; • 执行流程:
例 用for循环求 #include <stdio.h> main() { int i,sum=0; for(i=1;i<=100;i++) sum+=i; printf("%d",sum); } • for语句一般应用形式: for(循环变量赋初值;循环条件;循环变量增值) { 循环体语句; } • 说明: • for语句中expr1, expr2 ,expr3 类型任意,都可省略,但分号;不可省 • 无限循环: for(;;) • for语句可以转换成while结构 expr1; while(expr2) { 循环体语句; expr3; }
例:#include<stdio.h> main( ) { int i=0; for(;i<10;i++) putchar(‘a’+i); } 例:#include<stdio.h> main( ) { int i=0; for(i=0;i<10;i++) putchar(‘a’+i); } 例:#include<stdio.h> main( ) { int i=0; for(;i<10;) putchar(‘a’+(i++)); } 例:#include<stdio.h> main( ) { int i=0; for(;i<10;putchar(‘a’+i),i++) ; } 运行结果:abcdefghij
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); } } #include <stdio.h> main() { int i,c; for(i=0;(c=getchar())!='\n';i+=3) printf("%c ",i+c); } #include<stdio.h> main() { char c; for(;(c=getchar())!='\n';) printf("%c ",c); }
y f(x) 0 a a+h a+ih a+(i+1)h b x 例 (for)梯形法求数值积分
外循环 内循环 内循环 • 循环的嵌套 • 三种循环可互相嵌套,层数不限 • 外层循环可包含两个以上内循环,但不能相互交叉 • 嵌套循环的执行流程 • 嵌套循环的跳转 禁止: • 从外层跳入内层 • 跳入同层的另一循环 • 向上跳转 (4) for( ; ;) { …… do { …… }while(); …… while() { …… } …... } (3) while() { …… do { …… }while( ); ……. } (1) while() { …… while() { …… } …... } (2) do { …… do { …… }while( ); …... }while( );
3 2 1 9 1 18 2 2 6 4 3 3 9 6 27 12 8 4 36 4 5 45 10 15 5 54 18 12 6 6 7 14 63 7 21 8 24 8 72 16 27 9 9 81 18 j i …………….. 例 循环嵌套,输出九九表 /*ch5_5.c*/ #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); }
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++
break语句 功能:在循环语句和switch语句中,终止并跳出循环体或开关体 说明: break只能终止并跳出最近一层的结构 break不能用于循环语句和switch语句之外的任何其它语句之中 break和continue
while do 假(0) expr …… break; …... 真(非0) …… break; …… while 真(非0) expr 假(0)
for switch expr1 expr 假(0) expr2 case 真(非0) const 1 const 2 const n default …… break; …... 语句组n break; 语句组1 break; 语句组2 break; 语句组 break; …... expr3
例 break举例:输出圆面积,面积大于100时停止。 #define PI 3.14159 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); } }
例 break举例:小写字母转换成大写字母,直至输入非字母字符 #include <stdio.h> main() { int i,j; char c; while(1) { c=getchar(); if(c>='a' && c<='z') putchar(c-'a'+'A'); else break; } }
for expr1 while do 假(0) expr2 假(0) expr 真(非0) …… continue; …... …… continue; …... 真(非0) …… continue; …… while 真(非0) expr expr3 假(0) continue语句 功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断 • 仅用于循环语句中
例 求输入的十个整数中正数的个数及其平均值 /*ch5_12.c*/ #include <stdio.h> main() { int i,num=0,a; float sum=0; for(i=0;i<10;i++) { scanf("%d",&a); if(a<=0) continue; num++; sum+=a; } printf("%d plus integer's sum :%6.0f\n",num,sum); printf("Mean value:%6.2f\n",sum/num); }
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 分子:1,-1,1,-1… 分母:1,3,5,7,...
例5:/4=1-1/3+1/4-1/5+…±1/n (精度要求为1/n的绝对值<1e-6)。 • /*ch6_6.6.c*/ #include <studio.h> #include <math.h> main() {float pi=0.0,n=1.0,s=1.0,t; do {t=s/n; pi+=t; s*=-1.0; n+=2; } while (fabs(t)>=1e-6); printf(“pi=%f\n”,4*pi); }
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=1,f2=1 for i=1 to 20 输出f1,f2 f1=f1+f2 f2=f2+f1 例 求Fibonacci数列:1,1,2,3,5,8,……的前40个数
例2.求Fibonacci数列前40个数。 /*ch6_6.7.c*/ #include <stdio.h> main() {long int f1,f2; int i; f1=f2=1;printf(“\n”); for(i=1;i<=20;i++) {printf(“%12Ld%12Ld”,f1,f2); if(i%2==0) printf(“\n”); f1=f1+f2; f2=f2+f1; } }
读入m k=m i=2 当ik m被i整除 假 真 用break 结束循环 i=i+1 ik+1 假 真 输出:m”不是素数” 输出:m”是素数” 例 判断m是否素数
例2.输入一个正整数num,判断是否是素数。 /*ch6_6.8.c*/ #include <stdio.h> main() { int prime; unsigned int num; printf(“Input a positive integer:”); scanf(“%d”,&num); for(prime=2; prime<num; prime++) if(num%prime==0) break; if(prime==num) printf(“%5d is a prime.\n ”,num); else printf(“%5d is note a prime.\n ”,num); }
例2.求100~200间的全部素数。 /*ch6_6.9.c*/ #include <stdio.h> #include<math.h> main() {int m,k,i,n=0; for(m=101;m<=200;m+=2) {k=sqrt(m); for(i=2;i<=k;i++) if(m%i==0)break; if(i>=k+1) {printf(“%5d ”,m);n++;} if(n%10==0)printf(“\n”); } printf(“\n”); }
ABCDEFGHIJKLMNOPQRSTUVWXYZ 例 译密码 例如 Hello,world! 译成密码:Lipps,asvph!
例:译密码。(P119页) /*ch6_6.10.c*/ #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); } }
例:求从终端输入一个数字串,然后以逆序在终端上显示出来。例:求从终端输入一个数字串,然后以逆序在终端上显示出来。 #include <stdio.h> /* program to reverse the digits of a number.*/ #include <studio.h> main() {int number,right_digit; printf(“Please enter your number:\n”); scanf(“%d”,&number); do {right_number=number%10; printf(“%d”, right_digit); number=number/10 ; } while (number!=0) printf(“\n”); }
例:从终端输入一个字符,然后将小写字母转换成大写字母输出;当读到文件结束标志EOF(在studio.h中定义,是Ctrl_z或Ctrl_d或-1)时,程序结束。例:从终端输入一个字符,然后将小写字母转换成大写字母输出;当读到文件结束标志EOF(在studio.h中定义,是Ctrl_z或Ctrl_d或-1)时,程序结束。 • #include <stdio.h> main() {char c; do {c=getchar(); if(c>=‘a’&&c<=‘z’) c+=‘A’-’a’; putchar(c); } while (c!=EOF); }
例:从键盘输入若干整数,求其中的最大数和最小数。输入的数以0为中止标记。例:从键盘输入若干整数,求其中的最大数和最小数。输入的数以0为中止标记。 #include <stdio.h> main() {int x,max,min; scanf(“%d”,&x); max=min=x; for(;x!=0;) {if(x<min)min=x; if(x>max)max=x; scanf(“%d”,&x); } printf(“max=%d,min=%d\n”,max,min); }
例:下面程序段是找出整数的所有因子。 scanf(“%d”,&x); i=1; for(;i<=x;) {if(x%i==0)printf(“%3d”,i); i++; } 例:鸡兔共有30只,脚共有90个,问鸡兔各多少的程序片段。 for(x=1;x<=29;x++) {y=30-x; if(2*x+4*y==90) printf(“%d,%d”,x,y); }
例:e=1+1/1!+1/2!+1/3!...求e的近似值,精度要求为1e-6 。 #include <stdio.h> main() { int int i,double e,new; e=1.0; new=1.0; for(i=1;new>=1e-6;i++) { new/=(double)i; e+=new; } printf(“e=%f\n”,e); }
例:编一个程序验证下列结论:任何一个自然数n的立方等于n个连续奇数之和。例:编一个程序验证下列结论:任何一个自然数n的立方等于n个连续奇数之和。 例如:1^3=1;2^3=3+5;3^3=7+9+11。要求程序对每个输入的自然数计算并输出相应的连续奇数,直到输入的自然数为0止。 #include <studio.h> main() { int i,n,k,k1,m; scanf(“%d”,&n); while(n!=0) {k1=1; do{ k=k1;m=0; for(i=1;i<=n;i++) {m=m+k;k=k+2;} if(m==n*n*n)break; else k1=k1+2; }while(1); for(i=1;i<=n;i++) {printf(“%d ”,k1);k1+=2;} printf(“\n”); scanf(“%d”,&n); } }
应用举例:若用0至9之间不同的三个数构成一个三位数,下面程序将统计出共有多少种方法。应用举例:若用0至9之间不同的三个数构成一个三位数,下面程序将统计出共有多少种方法。 #include <stdio.h> main() {int i,j,k,count=0; for(i=1;i<=9;i++) for(j=0;j<=9;j++) if(i==j)continue; else for(k=0;k<=9;k++) if(k!=i&&k!=j) count++; printf(“count:%5d\n ”,count); }
例:百钱买百鸡问题。“鸡翁一值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡,问鸡翁、母、雏各几何?“例:百钱买百鸡问题。“鸡翁一值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱买百鸡,问鸡翁、母、雏各几何?“ 设x为公鸡数,y为母鸡数,z为小鸡数。根据题意:(不定方程求解问题,找出所有解) 。 x+y+z=100 5x+3y+z/3=100 #include <stdio.h> /*解一: ▲需50分钟*/ main() {int x,y,z; printf(“\n%14s%14s%14s\n”,”公鸡”,”母鸡”,”小鸡”) for(x=1;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==100) printf(“%15d%15d%15d\n ”,x,y,z);} 公鸡 母鸡 小鸡 0 25 75 4 18 78 8 11 81 12 4 84
例:百鸡百钱问题解二: ▲需4分钟。 /*ch6_12.c*/ #include <stdio.h> main() { int x,y,z; printf(“\n%14s%14s%14s\n”,”公鸡”,”母鸡”,”小鸡”) for(x=1; x<=20; x++) for(y=0; y<=33; y++) for(z=0; z<=100-x-y; z++) if(x+y+z==100&&5*x+3*y+z/3==100) printf(“%15d%15d%15d\n ”,x,y,z); } 公鸡 母鸡 小鸡 0 25 75 4 18 78 8 11 81 12 4 84
例:百鸡百钱问题解三: ▲需4秒钟。 /*ch6_12.c*/ #include <stdio.h> main() {int x,y,z; printf(“\n%14s%14s%14s\n”,”公鸡”,”母鸡”,”小鸡”) for(x=1; x<=20; x++) for(y=0; y<=33; y++) { z=100-x-y; if(5*x+3*y+z/3==100) printf(“%15d%15d%15d\n ”,x,y,z); } } 公鸡 母鸡 小鸡 0 25 75 4 18 78 8 11 81 12 4 84
/*ch6_12.c*/ #include <stdio.h> main() {int i,j; for(i=4;i>=1;i--) {for(j=1;j<=i;j++) putchar(‘C’); for(j=1;j<=4-i;j++) putchar(‘D’); putchar(‘\n’); } } 例:输出如下图形。 CCCCCCCD CCDDCDDD
/*ch6_12.c*/ #include <stdio.h> 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”); } } 例:输出如下图形。 ****** * * * * ******