http://hi.baidu.com/jsj08/blog 第六章 循环结构语句程序设计 内容概要:循环就是在满足一定条件时重复执 行的一段程序。 ? 概述 ? 构成循环的语句 ? 几种循环的比较 ? 循环的嵌套 ? break语句和continue语句 第六章 循环结构语句程序设计 §6.1 概述 C语言可实现循环的语句: ?用goto 和 if 构成循环 (不提倡) 当型循环 ?while 语句 直到型循环 ?do ~ while 语句 功能最强,多功能 ?for 语句 6.2 goto语句及用goto语句构成循环 ?功能:无条件转向goto语句一般格式: goto 语句标号; ?说明:语句标号用来定义程序中的某个位置 ?语句标号用标识符表示,不能用整数 ?滥用goto会破坏程序结构化,所以限制使用goto 语句 goto start goto 20 ?用途: ?与if语句一起构成循环结构 ?从循环体中跳转到循环体外 例 6.1 用if 和goto语句构成循环,求 循环初值 循环变量增值 #include void main() { int i,sum=0; i=1; loop: if(i<=100) { sum=sun+i; i++; goto loop; } printf("%d",sum); } 循环条件 sum=0+1 i=2 sum=1+2=3 i=3 sum=3+3=6 i=4 sum=6+4 i=5 …… sum=4950+100=5050 i=101 循环终值 循环体 ?6.3while语句 ?一般形式: while(表达式) 循环体语句; ?执行流程 : while 假(0) 表达式 循环体 真(非0) 例6.2 用while循环求 分析:这是一个累加求和的问题 循环变量初值 循环变量增值 #include void main() { int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } 循环条件 注意: ?i循环控制变量 求和项 ?sum和i的初值 sum是累计和, 所以初值要设为零 循环终值 i为了计数清晰 最好赋初值为1 注意控制好两头。 循环体 ?特点:先判断表达式,后执行循环体 ?说明: ?循环变量应有一个初值 ?循环体有可能一次也不执行 ?循环体可为任意类型语句 ?循环体如果包含一个以上的语句,应用花括 号括起来,以复合语句的形式出现,否则, while语句的范围只到while后第一个分号处 ?循环体中应有使循环趋向于结束的语句 如本例中的i++语句,否则就是容易死循环。 例 读函数 s=∑n s=1!+2!+3!....+n! t=n! #include main() {int k,s,n; printf("enter n :"); scanf("%d",&n); s=0;k=1; while(k<=n) {s+=k;k++;} printf("∑%d=%d\n ",n,s); } #include main() {int k,t,n; int s=0; printf("enter n :"); scanf("%d",&n); t=1;k=1; while(k<=n) {t*=k; s=s+t; k++;} printf("s=%d\n",s); printf("%d!=%d\n ",n,t); } ?6.4 do~while语 句 do ?一般形式: ?执行流程 : do 循环体语句; while(表达式); 分号不可省略 ,切记 循环体 真(非0) while 表达式 假(0) 例6.3 用do~while循环求 #include void main() { int i,sum=0; 先判后作 i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); } #include void main() { int i,sum=0; i=1; 先作后判 do { sum+=i; i++; }while(i<=100); printf("%d",sum); } ?特点:先执行循环体,后判断表达式 ?说明: ?至少执行一次循环体 ?do~while可转化成while结构 循环体 While循环 表达式 循环体 假(0) 真(非0) 例 6.4 while和do~while比较 #include void main() { int i,sum=0; scanf("%d",&i); while(i<=10) { sum+=i; i++; } printf("%d",sum); } 1↙ 55 11↙ 0 #include void main() { int i,sum=0; scanf("%d",&i); do { sum+=i; i++; }while(i<=10); printf("%d",sum); } 1↙ 55 11↙ 11 ?6.5 for语句 ?一般形式: for(表达式1 ;表达式2 ;表达式3) 语句 ?执行流程 : for 表达式1 表达式2 语句 表达式3 假(0) 真(非0) ?for语句一般应用形式: for(循环变量赋初值;循环条件;循环变量增值) { 循环体语句; } ?说明: 例_1 用for循环求 ?for语句可以转换成while结构 #include ?for语句中表达式1,表达式2 ,表达式3类型任意,都可 void main() 省略,但分号;不可省,表达式2 省略时,不判断循环 { 条件,也就是认为表达式2始终为真。 int i,sum=0; 表达式1; for(i=1;i<=100;i++) for(; ;) ?三个表达式可都省略: i=1; while(表达式2) for (i=1; ;i++) ;) for i=1;i<=100 sum+=i; i=1; ( (;i<=100 ;i++) { for sum=sum+i; {sum=sum+i; i++;} printf("%d",sum); (;i<=100 ;) for sum=sum+i; 循环体语句; {sum=sum+i; i ++} 表达式3; } } 说 明 1. 表达式1省略时,应在for前给循环变量赋 初值。 2. 表达式2省略时,不判断循环条件,将成为 “死循环”,需要在循环体内引入break语 句以退出循环。 3. 表达式3省略时,循环体内应加入使循坏条 件改变的语句。 4.在for中同时省略表达式1和表达式3,只有 表达式2,此时相当于while语句。 k=1; for(;k<=3;) {s=s+k; k++; } k=1; while(k<=3) {s=s+k; k++; } 5.表达式2一般是关系表达式或者逻辑表达式,但也可 以是数值表达式或字符表达式,只要其值不等于0就执 行循环体。 如:for( k=1 ;k-4 ;k++) s=s+k ; k-4是一个数值表达式 仅当k的值等于4时终止循坏。 表达式1或者表达式3省略的举例 例 :#include 例 :#include void main( ) void main( ) { int i=0; { int i; for(;i<10;i++) for(i=0;i<10;i++) putchar(‘a’+i putchar(‘a’+i); } } 例 :#include 运行结果:abcdefghij void main( ) { int i=0; for(;i<10;) putchar(‘a’+(i++) } 表达式1,3也可以是逗号表达式举例 例 :#include void main() sum=1+2+3...+100=5050 { int i,sum; for(sum=0,i=1;i<=100;i++) sum=sum+i; printf("%d\n",sum);} 例 : #include k=0*100+1*99+2*98+3*97....+50*50 void main() i=51 , j=49 { 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 void main() { char c; for(;(c=getchar())!='\n';) if(c>=65&&c<=90||c>=97&&c<=122)printf("%c",c); putchar(c); putchar('\n'); } 读入一个字符,不是回车 读入一个字符, 就输出一个字母 如果不是回车符就输出 注意:getchar()仅当遇到回车符时才开始执行,从键盘缓 冲区中取字符。 如: 输入 OK!回车 输出 OK! 而不是输出 OOKK!! ?6.6 循环的嵌套:一个循环体内包含另一个完整的 循环结构,成为循环嵌套 ?三种循环可互相嵌套,层数不限 ?外层循环可包含两个以上内循环,构成多重循环 ?嵌套循环的执行流程 外循环 (4) for( ; ;) (1) while() { …… (2) do (3) while() { …… do { …… 内循环 { …… while() { …… do do { …… }while(); { …… { …… } …… }while( ); }while( ); …... while() 内循环 …... ……. } { …… }while( ); } } …... } 注意: ?嵌套的循环控制变量不能相同 ?内循环变化快,外循环变化慢 ?正确定义循环体 ?循环控制变量和求解问题挂钩 例 1×1=1 1×2=2 1×3=3 1×4=4 1×5=5 1×6=6 1×7=7 1×8=8 1×9=9 循环嵌套,输出九九乘法表 前一个数字嵌套在后一个数的循环内 2×2=4 2×3=6 2×4=8 2×5=10 2×6=12 2×7=14 2×8=16 2×9=18 3×3=9 3×4=12 3×5=15 3×6=18 3×7=21 3×8=24 3×9=27 4×4=16 4×5=20 4×6=24 4×7=28 4×8=32 4×9=36 5×5=25 5×6=30 5×7=35 5×8=40 5×9=45 6×6=36 6×7=42 7×7=49 6×8=48 7×8=56 8×8=64 6×9=54 7×9=63 8×9=72 9×9=81 99乘法表代码: #include main() { int i,j; for(i=1;i<=9;i++) { for(j=1;j<=i;j++) { printf("%d×%d=%-3d",j,i,i*j); } printf("\n"); } printf("\n"); } §6.7 辅助控制语句 ?break语句 ?功能:在循环语句和switch语句中,终止并跳出 循环体或跳出switch结构 ?说明: ?break只能终止并跳出最近一层的结构 ?break不能用于循环语句和switch语句之外的 任何其它语句之中 ?If和goto构成的循环语句中不能用break语句 while 假(0) do …… break; …... 真(非0) while 表达式 表达式 …… 真(非0) break; …… 假(0) for 表达式1 switch 表达式2 假(0) 表达式 case 真(非0) …… break; const 1 语句组1 break; const 2 语句组2 break; …... const n 语句组n break; default 语句组 break; …... expr3 例_10:输出圆面积,面积大于100时停止 #define PI 3.14159 #include 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); } } 例_11:小写字母转换成大写字母,直至输入非字母字符 #include void main() { int i,j; char c; while(1) { c=getchar(); if(c>='a' && c<='z') putchar(c-'a'+'A'); else break; } } 例 判断m是否为素数 分析:素数是不能被其他整数整除的数,即如果m 是素数,则必然不存在i、t(i>1,t #include i的初值能 main() 否等于1 { int m, i, k; printf("input m:\n") scanf("%d",&m); k=sqrt( m ); for(i=2;i<=k;i++) if(m%i= =0)break; if(i>k)printf("%d是素数",m); else printf("%d是合数", m); } 例 判断m是否为素数 #include #include main() { int m, i, k; printf("input m:\n") scanf("%d",&m); k=sqrt( m ); for(i=2;i<=k;i++) if(m%i= =0)break; if(i>k)printf("%d是素数",m); else printf("%d是合数", m); } #include #include main() { int m, i, k,flag=1; printf("input m:\n") scanf("%d",&m); k= sqrt( m ); for(i=2;i<=k;i++) if(m%i= =0){flag=0,break;} if(flag)printf("%d是素数",m); else printf("%d是合数", m); } ?continue语句 提前下次循环 for 表达式1 表达式2 ?功能:结束本次循环,跳过循环体中尚未执行的 语句,进行下一次是否执行循环体的判断 ?仅用于循环语句中 while 假(0) do 表达式 假(0) 真(非0) …… …… 真(非0) …… continue; … continue; …... 真(非0) 表达式3 continue; ... while 表达式 假(0) 例 求输入的十个整数中正数的个数及其平均值 #include void 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); } 例 把100~200之间的不能被3整除的数输出 本次循环结束 #include 循环体的剩余语句 void main() 被忽略 { int n; 执行表达式3,进 for(n=100;n<=200;n++) 入下一次循环。 { if(n%3= =0) continue; printf("%d\n",n); if(n%3)printf("%d",n) } } ?综合程序举例 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 #include #include 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) } 例 求100~200间的全部素数,并且按照每行10个输出 判断m是否为素数 #include #include 1、需要一个变量来控制每行输出10个数 void main() { int m,i,k; int n=0 scanf("%d",&m); 2、数据范围已经给定。所以删除此行 for(m=101;m<=200;m=m+2) k=sqrt(m); for(i=2;i<=k;i++) 3、输出也要改 if(m%i==0) break; if(i>k) printf("%d is a prime number\n",m); if(i>=k+1) {printf("%d ",m);n=n+1;} else printf("%d is not a prime number\n",m); if(n%10==0) printf("\n"); } 整理完后得到完整的程序:求100~200之间的全部素数 #include #include 为什么是m=m+2? void main() { int m,i,k,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"); } printf("\n"); } 例 打印图形 分析: 1、图形每行的起始位置相同 2、每行的字符数同 3、用一重循环控制输出行数即可 #include main() {int row=1; for(;row<=5;row++) printf("********\n"); } 分析: 1、起始不同,空格数递增 1 2、每行的字符数同 3、用二重循环实现 控制行数 外循坏控制输出行数 内循环控制输出空格数 int row=1,col; { for(col=1;col<=5-row;col++) printf(" "); printf("********\n");} #include main() {int row=1 , col ; for( ;row<=5 ; row++) { for(col=1;col<=5-row;col++) printf(" "); printf("********\n"); } } 考虑: 若起始位置为20, 怎么办? 分析: 1、每行起始位置不同: 空格数 20-row 2、每行的字符数不同 字符数 2*row-1 3、用二重循环实现 外循环控制输出行数 两个并列内循环控制 每行空格数和*字符数 #include main() {int row=1,col; for(;row<=5;row++) {for(col=1;col<=20-row;col++) printf(" "); for(col=1;col<=2*row-1;col++) printf("*"); printf("\n"); } } 课外作业 1、两个乒乓球队进行比赛,各出3人,甲队 为A ,B,C3人,乙队为X,Y,Z3人。 已抽签决定比赛名单。有人向队员打听比 赛名单,A说他不和X比,C说他不和X,Z 比,请编程找出3对赛手的名单。