320 likes | 429 Vues
第 5 章 循环结构. 5.1 while 语句 5.2 do-while 语句 5.3 for 语句 5.4 三种循环语句的比较 5.5 循环的嵌套 5.5 break 语句和 continue 语句 5.7 综合实例. 第 5 章 循环结构. 循环结构 又称重复结构,可以完成重复性、规律性的操作。 C 语言共有三种类型的循环语句: while 当循环 do-while 直到循环 for 多功能.
E N D
第5章 循环结构 5.1 while语句 5.2 do-while语句 5.3 for语句 5.4 三种循环语句的比较 5.5 循环的嵌套 5.5 break语句和continue语句 5.7 综合实例
第5章 循环结构 • 循环结构又称重复结构,可以完成重复性、规律性的操作。 • C语言共有三种类型的循环语句: • while 当循环 • do-while 直到循环 • for 多功能
假 表达式 真 循环体 5.1 while语句 While语句的一般格式: while(表达式) { 循环体 } 流程图: 功能:先判断表达式的值的真假,若为真(非零)时,就执行循环体的语句系列,然后回头再次判断表达式的值,如此重复;若为假(零)则退出循环结构。 被重复执行的部分(可能由若干语句组成)称为循环体。
循环控制表达式 循环控制变量 循环体 5.1 while语句 【例5.1】编程实现1+2+3+…+100。 int i,sum=0; i=1; while(i<=100) { sum+=i; i++; }
5.1 while语句 需要注意的是: ⑴循环体如果包含一个以上的语句,应该用花括号括起来,以复合语句的形式出现。 ⑵在循环体中应该有使循环趋向于结束的语句。如无此语句,循环将永不结束。比如改变循环控制变量值的语句。 (3)循环体可以为空,如从键盘输入字符,直到输入为A为止:while((c=getchar())!=‘A’);
5.1 while语句 【例5.2】看一个简单的印数程序。 # include "stdio.h" main() { int number=0; while(number<=1) { number++; printf("%d\n",number); } } 运行结果为: 1 2
5.1 while语句 【例5.3】 第二个印数程序。 # include "stdio.h" main() { int number=0; while(number++<=1) printf("*%d\n",number); printf("**%d\n",number); } 运行结果为: *1 *2 **3
# include "stdio.h" void main() { char c; int alpha,digit,other; alpha=digit=other=0; printf("input characters end of newline:\n"); while((c=getchar())!='\n') if (c>='a'&&c<= 'z'|| c>= 'A'&&c<= 'Z') alpha++; else if (c>='0'&&c<= '9') digit++; else other++; printf("alpha=%d\ndigit=%d\nother= %d\n", alpha,digit,other); } 5.1 while语句 【例5.4】 输入一行字符,按字母、数字和其它分成三类,分别统计各类字符的数目(换行符'\n'不在统计范围内)。 字母的条件: c>='a'&&c<= 'z'|| c>= 'A'&&c<= 'Z'成立,则c为一个字符。 数字的条件: c>=‘0’&&c<= ‘9’成立,则c为一个数字。 算法: ⑴ 将各计数器变量置初值为0。 ⑵ 提示用户输入一行字符。 ⑶ 读入一个字符。 ⑷ 检查c是否为换行符‘\n’,如果不是,则检查c符合哪种字 符条件,并将相应计数器变量的值加1,然后转步骤⑶(循 环);如果c是'\n'字符,则结束循环,转步骤⑸。 ⑸ 输出计数结果。
main() { int men=0,women,children; while(men<=8) { women=0; while(women<=11) { children=0; while(children<=36) if(8*men+6*women+children==72 &&men+women+children==36) { printf("\nmen is %d",men); printf("\twomen is %d",women); printf("\tchildren is %d\n",children); } children++;} women++; } men++; } } 【例5.6】搬砖问题。(36块砖,36人搬;男搬4,女搬3,两个小孩抬一砖。要求一次全搬完,问男、女、小孩各若干)设计搬砖问题的程序。 对于men: men=0; while(men<=8) {找满足题意的women,children; men++; } 下面再进一步细化,找每一个women下的children: men=0; while(men<=8) {women=0; while(women<=11) {找满足题意的children; women++;} men++; } 分析:男人(men)的可能取值范围为:0-8; 女人(women)的可能取值范围为:0-11; 小儿(children)的可能取值范围为:0-36; men=0; while(men<=8) {women=0; while(women<=11) { children=0; while(children<=36) {若: 8*men+6*women+children=72 children++;} women++;} men++; }
循环体 真 表达式 假 5.2 do-while语句 • do-while语句的一般格式是: • do • { • 循环体 • } • while (<表达式>); 功能: 先执行一次循环体,再判断表达式的真假。若表达式为真(非0)则再次执行循环体,重复执行;直到表达式为假(0)时退出循环结构。
5.2 do-while语句 和while语句不同的是:while语句先判断<表达式>是否成立,然后再执行循环体。而do-while语句是先执行循环体一次,然后再去判断<表达式>是否成立。 注意:while后面的分号(;)不能少。
5.2 do-while语句 【例5.7】用do-while语句实现【例5.1】。 # include "stdio.h" void main() { int i,sum=0; i=1; do { sum=sum+i; i++; } while(i<=100); printf("%d\n",sum); }
【例5.8】while和do-while循环的比较。 main() main() {int sum=0,i; {int sum=0,i; scanf("%d",&i); scanf("%d",&i); while(i<=10) do { { sum=sum+i; sum=sum+i; i++; i++; } }while(i<=10); printf("sum=%d\n",sum); printf("sum=%d\n",sum); } } 第一次运行 第一次运行 1 1 sum=55 sum=55 再运行一次: 再运行一次: 11 11 sum=0 sum=11
例:求100以内的奇数之和和偶数之和 while(n<100) { js+=n; os+=n+1; n+=2; } printf(“sum(js)=%d,sum(os)=%d”,js,os); while(n<=100) { if(n%2==0) os+=n+1; else js+=n; n++; } printf(“sum(js)=%d,sum(os)=%d”,js,os);
5.3 for语句 for语句的一般形式: for(<表达式1>;<表达式2>;<表达式3>) <语句>; 注意:三个表达式之间必须用分号;隔开。
5.3 for语句 其执行过程如下: ①首先计算<表达式1>。 ②求<表达式2>的值,若其值为非零,执行<语句>,然后转③执行,若<表达式2>的值为零,则结束for语句。 ③求解<表达式3>,转②执行。 注意: for循环的三个表达式可以是C语言中任何有效的表达式。
5.3 for语句 【例5.9】 求自然数列前n 项的和。 main() { int sum=0,i,n; printf("please input n: "); scanf("%d",&n); for(i=1;i<=n;i++) sum+=i; printf("sum=%d\n",sum); } please input n:0↙ sum=0 please input n:1↙ sum=1 please input n:10↙ sum =55 please input n:100↙ sum=5050
5.3 for语句 【例5.9】 从键盘上输入10个数,求其平均值。 输入如下数据: 89 72 83 96 50 98 78 93.5 91 86 程序运行结果: average=83.650000 main() { int i; float f,sum; for(i=1,sum=0;i<11;i++) { scanf("%f",&f); sum+=f; } printf("average=%f\n",sum/10); }
5.3 for语句 for语句的其他形式: 1.for语句中的减值 for(counter=100;counter>=10;counter-=5) printf("%d",counter); 2.<表达式1>为空语句(移到for语句前面执行) i=1; for( ;i<=n;i++) 3 .<表达式3>为空语句(移到for语句里面执行) for(i=0;elem[i]!=x,i<=10;) i++;
5.3 for语句 4.<表达式1>和<表达式3>可以是逗号表达式 for(i=1,sum=0;i<=n;sum+=i,i++) ; 5.常用空循环来延长时间 for(t=0;t<time;t++); 6.无限循环形式(表达式2为空) for循环可以省略三个表达式,但是分号”;”不可省略。 for( ; ;) <语句>; 7. 表达式2可以是数值表达式,或逻辑表达式 for(k=1;k-4;k++)
5.3 for语句 【例5.12】相传古代印度国王舍罕要褒奖他的聪明能干的宰相达依尔(国际象棋的发明者),问他需要什么,达依尔回答说:“国王只要在国际象棋的棋盘上的第一个格子上放一粒麦子,第二个格子上放上2粒,第三个格子上放上4粒,依次类推,每格是前一格的2倍,一直放到64格,我就感恩不尽了”。国王答应了,结果全印度的粮食用完还都不够。国王很纳闷,怎么也算不清这笔帐。请用C语言编程来算一下。(1m3小麦大约1.42×108粒) # include "stdio.h" main() { int n; double v,sum=0.0,t=1.0; for(n=0;n<64;n++) { sum+=t; t*=2; } printf("sum=%e",sum); v=sum/1.42e8; } 分析 :需要计算sum=1+2+22+23+24+25+…+264算出小麦 的颗粒数 运行结果: sum=1.84467e19 v=1.29907e11
5.4 三种循环语句的比较 1. C语句提供的三种循环控制结构,可以用来处理同一问题。一般情况下可以相互代替。 2. while和do-while循环结构,只设置了结束循环的条件。循环体内需要设置打破循环条件而使循环趋向结束的语句 3. do-while 循环和while 循环相似,但do-while 循环先运行循环体,然后再进行循环结束条件的测试,循环体最少运行一次。 4. 对于已知重复次数的循环,使用for结构更方便、更清晰。而仅知道循环结束的条件,不知道循环次数的用while 循环和do-while 循环更简洁。
5.5 循环的嵌套 1.循环嵌套的概念 在一个循环结构中又包含另一个循环结构,称为循环的嵌套。 2.循环嵌套的形式 前面介绍了三种类型的循环,它们自己本身可以嵌套,也可以互相嵌套。 (4) (5) (6) for ( ) while ( ) for ( ) { ... { … { … while ( ) for ( ) do {...} {…} {…} ... … while ( ) ; } } … } (1) (2) (3) for ( ) while ( ) do { ... { … { … for ( ) while ( ) do {...} {…} {…} ... … while( ); } } … }
5.5 循环的嵌套 3. 注意: (1)嵌套的循环控制变量不能相同 (2)外循环执行一次,内循环执行一轮。即只有当内层循环结束时,外层循环才进入下一次循环。 内循环变化快,外循环变化慢 (3) 使用相关语句可以从循环体内转入循环体外,提前结束循环。 for(i=1;i<=9;i++){ for(j=1;j<=i;j++) printf(“%d*%d=%d”,i,j,i*j); printf(“\n”);}
# include "stdio.h" main() { int i,j,n; long sum,term; printf("请输入n:\n"); scanf("%d",&n); for(sum=0,i=1;i<=n;i++) { term=1; j=1; do { term*=i; } while(++j<=i); sum+=term; } /*for结束*/ printf("sum=%ld\n",sum); } 5.5 循环的嵌套 4. 应用 【例5.14】 计算s=11+22+33+…+nn,n由终端输入。 分析:设每一项的底用整型变量i表示,i从1开始每次增1直至n,考虑到溢出,i的i次方及各项之和分别用长整型变量term和sum表示。term=i*i*i*…*i,即i个i连乘,显然计算term要用循环来实现;sum=∑term,即n个term连加,这也要用循环实现。因而计算s的算法是一个二重循环,外层循环(简称外循环)控制项数,内层循环(简称内循环)控制每项i的连乘次数。 运行结果: 请输入n:5 sum=3413
# include "stdio.h" void main(void) { int i,j; /* output table head */ printf("%4c",'*'); for(i=1;i<=9;++i) printf("%4d",i); printf(“\n”); /* output table body */ for(i=1;i<=9;++i) { printf("%4d",i); for(j=1;j<=9;++j) if(j<=i) printf("%4c",' ' ); else printf("%4d",i*j); printf("\n"); } /* end of external for */ } 5.5 循环的嵌套 算法: ﹙1﹚输出表头(顶行): 1﹚输出*。 2﹚输出1至9。 3﹚输出换行。 ﹙2﹚输出表体(1至9行): 1﹚外循环变量i(行号)置初值1。 2﹚如果i<=9,输出一行: ●输出行号(被乘数)。 ●列号j(乘数)从1至9,对每一个j,如果j>=i则输出i*j,否则输出空格。 ●输出换行。 ●i=i+1,转2),如果i>9,结束循环。 【例5.17】用如下格式输出乘法九九表。 * 1 2 3 4 5 6 7 8 9 1 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 9 12 15 18 21 24 27 4 16 20 24 28 32 36 5 25 30 35 40 45 6 36 42 48 54 7 49 56 63 8 64 72 9 81 分析:从表中可见,整个表分为表头(顶行)和表体(1~9行)两部分,表体是二维结构,因而输出表体部分要用二重循环。
5.5 循环的嵌套 多重循环的使用要点: ⒈ 对于多重循环,特别要注意给与循环有关的变量赋初值的位置。 ⒉ 内、外循环变量不应同名,否则,将造成循环控制混乱,导致死循环或计算结果错误。 ⒊ 应正确书写内、外循环的循环体:需要在内循环中执行的所有语句必须用{}括起来组成复合语句作为内循环体;属于外循环的语句应放在内循环体之外,外循环体之中。 ⒋ 不应在循环中执行的操作应放在进入最外层循环之前或最外层循环结束之后。
5.6 break语句和continue语句 5.6.1 break语句 5.6.2 continue语句
5.6.1 break语句 break语句的形式为: break; 功能:跳出当前的switch语句或循环语句。 break语句对于减少循环次数,加快程序执行起着重要的作用。
5.6.1 break语句 【例5.18】从键盘上输入任意个数,求其平均值,当输入值为0时,计算结束。 main() { int i; float f,sum; for(i=0,sum=0.0; ;i++) { scanf ("%f",&f); if (f= =0.0) break; sum+=f; } if(i= =0) printf("no data"); else printf("average=%f\n",sum/i); }
5.6.2 continue语句 continue语句的一般形式为: continue; 功能:结束本次循环,即跳过循环语句中尚未执行的语句,接着进行循环条件的判定。 continue语句只用在for,while, do-while等循环体中,常与if语句一起使用,用来加速循环。
5.6.2 continue语句 【例5.20】输出100以内能被7整除的数。 main() { int i; for(i=1;i<=100;i++) { if(i%7!=0) continue; printf("%4d",i); } }