《C语言第4章程序设计的三种基本结构.ppt》由会员分享,可在线阅读,更多相关《C语言第4章程序设计的三种基本结构.ppt(89页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第四章第四章 程序设计的三种基本结构程序设计的三种基本结构 第四章第四章 程序设计的三种基本结构程序设计的三种基本结构 前前面面章章节节介介绍绍了了程程序序设设计计中中用用到到的的一一些些基基本本要要素素(常常量量、变变量量、运运算算符符、表表达达式式等等),它它们们是是构构成成程程序序的的基基本本成成份份。程程序序设设计计是是为为了了完完成成某某一一项项任任务务而而编编写写的的指指令令集集合合,它它是是人人与与计计算算机机进进行行信信息息交交流流的的工工具具。本本章章将将介介绍绍为为编编写写简简单单的程序所必需的一些内容及程序设计的三类语句的程序所必需的一些内容及程序设计的三类语句。v4.1
2、 C语句概述语句概述任何一种程序设计语言都具有特定的语法规则和一定的表现形任何一种程序设计语言都具有特定的语法规则和一定的表现形式。按照一定的格式和构成规则书写程序,不仅可以使程序设式。按照一定的格式和构成规则书写程序,不仅可以使程序设计人员和使用程序的人员易于理解,更重要的是把程序输入到计人员和使用程序的人员易于理解,更重要的是把程序输入到计算机时,计算机能够充分识别,并且正确执行它。计算机时,计算机能够充分识别,并且正确执行它。C程序是程序是用用C语句来书写的,语句来书写的,C语句可以分为以下三类:语句可以分为以下三类:1.控制语句控制语句控制语句完成一定的控制功能。控制语句完成一定的控制
3、功能。C只有以下只有以下9种控制语句:种控制语句:(1)if()else (条件语句条件语句)(2)for()(循环语句循环语句)(3)while()(循环语句循环语句)(4)dowhile()(循环语句循环语句)(5)continue (结束本次循环语句结束本次循环语句)(6)break (终止执行终止执行switch或循环语句或循环语句)(7)switch (多分支选择语句多分支选择语句)(8)goto (转向语句转向语句)(9)return (从函数返回语句从函数返回语句)以上以上9种控制语句中的种控制语句中的()表示其中是一个条件,表示其中是一个条件,表示内嵌语表示内嵌语句。句。2表达
4、式语句表达式语句表达式语句由表达式加上分号表达式语句由表达式加上分号“;”组成。它包括三种基本组成。它包括三种基本语句。语句。(1)赋值语句赋值语句 执行赋值语句就是计算表达式的值,并将其赋执行赋值语句就是计算表达式的值,并将其赋给左边的变量。给左边的变量。例如:例如:z=x+y;i+;(2)函数调用语句函数调用语句 由一次函数调用加一个分号构成一个语句。由一次函数调用加一个分号构成一个语句。例如:例如:clrscr();(3)空语句空语句 空语句是只有一个分号而没有表达式的语句。下空语句是只有一个分号而没有表达式的语句。下面是一个空语句:面是一个空语句:;它只是形式上的语句,什么也不做。有时
5、用来作被转向点,它只是形式上的语句,什么也不做。有时用来作被转向点,或循环语句中的循环体,表示循环体什么也不做。或循环语句中的循环体,表示循环体什么也不做。3复合语句复合语句用用“”把一些语句括起来成为复合语句,也称为分程把一些语句括起来成为复合语句,也称为分程序。如:序。如:z=a+b;t=z/100;couttendl;复合语句内的各条语句都必须以分号复合语句内的各条语句都必须以分号“;”结尾,在右括号结尾,在右括号“”外面不能加分号。外面不能加分号。C语言允许一行写几个语句,也允许语言允许一行写几个语句,也允许一个语句分开写在几行上,书写格式无固定要求一个语句分开写在几行上,书写格式无固
6、定要求。4.2顺序结构程序设计顺序结构程序设计顺序结构程序是一组按书写顺序执行的语句。顺序结构程序顺序结构程序是一组按书写顺序执行的语句。顺序结构程序中的语句由赋值语句和输入、输出语句组成。它是中的语句由赋值语句和输入、输出语句组成。它是C程序中最程序中最简单、最基本的一种结构,是进行复杂程序设计的基础。执简单、最基本的一种结构,是进行复杂程序设计的基础。执行顺序如图行顺序如图4.1。图.1执行a执行b(b)执行a执行b(a)4.2.1顺序结构程序设计举例顺序结构程序设计举例下面介绍几个顺序结构程序设计的例子。下面介绍几个顺序结构程序设计的例子。例例4.1 有三个电阻并联,其阻值分别为有三个电
7、阻并联,其阻值分别为10、20、30,求并联后的电阻。计算并联电阻的公式是:,求并联后的电阻。计算并联电阻的公式是:r=1/(1/r1+1/r2+1/r3)。#includevoid main()float r,r1,r2,r3;r1=10;r2=20;r3=30;r=1/(1/r1+1/r2+1/r3);cout并联电阻并联电阻r=rendl;运行结果:运行结果:并联电阻并联电阻r=5.455例例4.2 从键盘输入一个大写字母,要求改用小写字母从键盘输入一个大写字母,要求改用小写字母输出。输出。大写字母的大写字母的ASCII码值比小写字母的码值比小写字母的ASCII码值小码值小32,因此将大
8、写字母的因此将大写字母的ASCII码值加码值加32便可得到相应的小便可得到相应的小写字母的写字母的ASCII码值,根据此思路编程如下。码值,根据此思路编程如下。#include void main()char c1,c2;cinc1;c2=c1+32;coutc1,c20。众所周知,一元二次方程的根为:众所周知,一元二次方程的根为:x1x2可以将上面的分式分为两项:可以将上面的分式分为两项:p=,q=,x1=p+q,x2=p-q根据以上分析,画出根据以上分析,画出N-S流程图如图流程图如图4.2所示所示。float a,b,c,disc,x1,x2,p,q输入a,b,c计算disc=b*b-4
9、*a*c计算p=-b/(2*a)计算q=sqrt(disc)/(2*a)计算x1=p+q,x2=p-q输出x1,x2图4.2据此编写源程序如下:据此编写源程序如下:#include#include void main()float a,b,c,disc,x1,x2,p,q;cout请输入请输入a、b、c的值:的值:abc;disc=b*b-4*a*c;p=-b/(2*a);q=sqrt(disc)/(2*a);x1=p+q;x2=p-q;coutx1=x1endl;coutx2=x2y)coutxy)coutxendl;else couty500)cost=0.15;else if(numbe
10、r300)cost=0.10;else if(number100)cost=0.075;else if(number50)cost=0.05;elsecost=0;这种if语句的执行过程见图4.6。三种if结构比较:三种形式的if语句中在if后面都有“表达式”,一般为逻辑表达式或关系表达式。第二、三种形式的if语句中,在每个else前面有一个分号,整个语句结束处有一个分号。其中else子句不能做为语句单独使用,它必须是if语句的一部分,与if配对使用。在if和else后面可以只含一个内嵌的操作语句,也可以有多个操作语句,但此时必须用一对花括号“”将几个语句括起来成为一个复合语句。如:if(xy
11、)x=x*x;y=y*y;coutx*x=xendl;couty*y=yendl;elsecoutxy 不做运算b 假a,b值互换输出a,b值图4.7例4.4输入两个整数,按由小到大的次序输出这两个数。这个问题算法很简单,只做一次比较即可。但需要用到一个中间变量t做为媒介,当输入变量ab时,进行交换,先将a的值存入t,再将b的值存入a,然后将t中保存的a的原值存入b,运行前t中无固定值,运行后t中存有a的值。N-S流程图如图4.7所示。据此写出源程序如下:#include void main()int a,b,t;cinab;if(ab)t=a;a=b;b=t;/交换变量a,b的值 couta
12、 bendl;执行情况为:5 35注意:若交换变量a,b的值,直接用如下两条语句做,行不行?a=b;b=a;例4.5输入3个整数a,b,c,要求按由小到大的顺序输出。算法N-S流程图如图4.8所示。据此算法写出源程序如下:#include void main()int a,b,c,t;int a,b,c,t cinabc;if(ab)t=a;a=b;b=t;if(ac)t=a;a=c;c=t;if(bc)t=b;b=c;c=t;couta b cb真 假a,b互换 ac真 假a,c互换 bc真 假b,c互换输出a,b,c图4.8例4.6 从键盘输入某位同学的各科成绩,数学(sx)、英语(yy)
13、、计算机(jsj),要求判断该同学是否有不及格,如有则输出不及格课程名称和成绩,否则不输出。算法N-S流程图如图4.9所示。据此算法写出源程序如下:#include void main()int sx,yy,jsj;cinsxyyjsj;if(sx60)cout数学 sxendl;if(yy60)cout英语 yyendl;if(jsj60)cout计算机 jsjendl;运行情况为:567886数学 56 int sx,yy,jsj输入sx,yy,jsjsx60真 假输出sxyy60真 假输出yyjsj89真 假 score74 真 假 score60 真 假输出优 输出良 输出及格 输出不
14、及格图4.10例4.7 编写一程序,根据学生的分数来划分成绩的等级。其划分规则如下:分数 等级90100 优7589 良6074 及格059 不及格假定考分变量为score,学号变量为num,则其算法N-S流程图如图4.10所示。据此算法写出源程序如下:#include void main()int score,num;cinnumscore;if(score89)coutnum:优74)coutnum:良60)coutnum:及格endl;else coutnum:不及格y真 假zx yx真 假 真 假max=z max=y 输出max图4.11例4.8 从键盘输入三个数,求其中最大数。算法
15、N-S流程图如图4.11所示。据此算法写出源程序如下:#include void main()int x,y,z,max;cinxyz;max=x;if(zy)if(zx)max=z;elseif(yx)max=y;coutmaxb)max=a;else max=b;可以用下面的条件运算符来处理:max=(ab)?a:b;其中“(ab)?a:b”是一个“条件表达式”。它是这样执行的:如果(ab)条件为真,则条件表达式取值a,否则取值b。条件运算符要求有3个操作对象,称三目(元)运算符,它是C语言中唯一的一个三目运算符。条件表达式的一般形式为表达式1?表达式2:表达式3它的执行过程如图4.12所
16、示。表达式1条件表达式取表达式2的值条件表达式取表达式3的值假面具真图4.12说明:(1)条件运算符的执行顺序:先求解表达式1,若为真则求解表达式2,此时表达式2的值就作为整个条件表达式的值。若表达式1的值为假,则求解表达式3,表达式3的值就是整个条件表达式的值。max=(ab)?a:b执行结果就是将条件表达式的值赋给max。也就是将a和b中大者赋给max。(2)条件运算符优先于赋值运算符,因此上面赋值表达式的求解过程是先求解条件表达式,再将它的值赋给max。条件运算符的优先级别比关系运算符和算术运算符都低。所以max=(ab)?a:b 括号可以不要,完全等价于max=ab?a:b如果有ab?
17、a:b+1相当于ab?a:(b+1),而不相当于(ab?a:b)+1.(3)条件表达式不能取代一般的if语句,只有在if语句中内嵌的语句为赋值语句(且两个分支都给同一个变量赋值)时才能代替if语句。以下语句则无法用一个条件表达式代替。if(ab)couta;else coutb;但可以用下面语句代替:coutb?a:b;即将条件表达式的值输出。(4)条件表达式中,表达式1的类型可以与表达式2和表达式3的类型不同。如x?a:bx是整型变量。若x0,则条件表达式的值为a;若x=0,则条件表达式的值为b。例4.9 输入一个字符,判别它是否大写字母,如果是,将它转换成小写字母;如果不是,不转换。输出最
18、后得到的字符。本题算法比较简单,在此直接给出源程序如下:#include void main()char ch;cinch;ch=(ch=A&ch=Z)?(ch+32):ch;coutch;运行情况为:Aa条件表达式中的(ch+32),其中32是小写字母和大写字母的ASCII码的差值。例4.9 输入一个字符,判别它是否大写字母,如果是,将它转换成小写字母;如果不是,不转换。输出最后得到的字符。本题算法比较简单,在此直接给出源程序如下:#include void main()char ch;cinch;ch=(ch=A&ch=Z)?(ch+32):ch;coutch;运行情况为:Aa条件表达式中
19、的(ch+32),其中32是小写字母和大写字母的ASCII码的差值。4.3.3 switch语句switch语句是多分支选择,也称为开关分支或开关语句。在上一节中介绍了如何用嵌套的if结构来解决多路选择问题,我们还可以利用本节将要介绍的switch语句来解决多路选择问题。switch语句的一般形式如下:switch(表达式)case 常量1:语句1或空;case 常量2:语句2或空;case 常量n;语句n或空;default:语句n+1或空;执行switch开关语句时,将变量逐个与case后面的常量进行比较,若与其中一个相等,则执行该常量下的语句,默认一直执行到语句体结束,除非遇有break
20、转向语句跳出执行体,若不与任何一个常量相等,则执行default后面的语句。说明:(1)switch后面括弧中的表达式只能是整形、字符型。case后面的常量表达式的类型必须与其匹配。(2)case语句仅起标号的作用,所以每一个case的常量表达式的值必须互不相同,否则就会出现矛盾的现象(对表达式的同一个值,有两种或多种执行方案)。(3)每个case或default后面的语句可以是复合语句,但不需要使用“”括起来。例4.10 从键盘输入一个整型数,根据输入值的大小输出不同的值。#include void main()int test;cintest;switch(test)/变量为整型数的开关语
21、句 case 1:cout test;break;/退出开关语句 case 2:cout test+1;break;case 3:couttest+2;break;default:coutError;运行情况为:23 6Error(4)case和default的出现次序不影响执行结果。(5)多个case可以共用一组执行语句,如:case A:case B:case C:cout60endl;(6)ifelse ifelse结构用于多种条件的多次判断的情况,而switch结构则用于一次条件判断多种结果的情况,二者可以互相补充,有时也可以等价使用。(7)switch结构可以用break结束,而if
22、else ifelse结构不能使用break结束。输入a,b,c ab 真 假bc ac真 假 真 假max=c max=b max=c max=a输出max图.134.3.4 选择结构程序设计举例例4.11从键盘输入三个数,求其中最大数。算法N-S流程图如图4.13所示。据此算法写出源程序如下:#include void main()int a,b,c;coutabc;if(ab)if(bc)coutmax=cendl;elsecoutmax=bendl;else if(ac)coutmax=cendl;elsecoutmax=aendl;运行情况为:123456max=56结合例4.8可知
23、,同一问题可以有不同的算法程序。例4.12编写一个程序:将用户输入的分数按以下规则转换成相应的等级:分数:90100 等级:优分数:8089 等级:良分数:7079 等级:中分数:6069 等级:及格分数:059 等级:不及格解此问题,先要构想解题的方法。分析题目所给的条件,可以发现等级共分为五个档次,而每个档次所对应的成绩(score)的下限都是10的倍数。第一档次,成绩的下限为90分,等级为优;第二档次,成绩的下限为80分,等级为良;第三档次,成绩的下限为70分,等级为中;第四档次,成绩的下限为60分,等级为及格;第五档次,成绩的下限为0,等级为不及格。以上各档次score的下限分别为90
24、,80,70,60,0,它们分别为10的9倍、8倍、7倍、6倍、0倍 scoreb等级901009优80898良70797中60696及格0590不及格也就是说,当score的值不足六个10分时,等级为不及格;当score的值满六个10分而未满七个10分时,等级为及格;当score的值满七个10分而未满八个10分时,等级为中;当score的值满八个10分而未满九个10分时,等级为良;当score的值满九个10分时,等级为优。以n代表score的值满n个10分,可以将上表改写为 scoren等级901009,10优80898良70797中60696及格0595,4,3,2,1,0不及格根据此表,
25、只要找出n的值,就可以确定等级。n的值可以由下面的公式求出:n=(int)(score/10)说明:(int)(score/10)的作用是将(score/10)的值进行强制类型转换,得到一个整型值。例如当score=68时,n的值为6;score的值为54时,n的值为5;score的值为89时,n的值为8。算法N-S流程图如图4.14所示。输入score计算(int)(score/10)真 10或9 假 真 8 假 真 7 假 真 6 假真 5,4,3,2,1,0 假输出优 输出良 输出中 输出及格 输出不及格 输入错误 图4.14据此算法写出源程序如下:#include void main(
26、)float score;coutscore;switch(int)(score/10)case 10:case 9:cout优endl;break;case 8:cout良endl;break;case 7:cout中endl;break;case 6:cout及格endl;break;case 5:case 4:case 3:case 2:case 1:case 0:cout不及格endl;break;default:cout输入错误endl;运行情况为:请输入学生成绩:78中例4.13 编写程序,判断某一年是否闰年。分析:用变量leap代表是否闰年的信息。若闰年,令leap=1;非闰年,
27、leap=0。最后判断leap是否为1(真),若是,则输出“闰年”信息。年号能被4整除?否:非闰年能:能被100整除?否:是闰年能:能被400整除?否:非闰年能:是闰年判断是否闰年的方法如下:年号能被4整除?否:非闰年能:能被100整除?否:是闰年能:能被400整除?否:非闰年能:是闰年由以上分析,编写源程序如下:#include void main()int year,leap;cinyear;if(year%4=0)if(year%100=0)if(year%400=0)leap=1;else leap=0;else leap=1;else leap=0;if(leap)coutyear
28、is;elsecoutyear is not;couta leap year.endl;运行情况为:1970 1970 is not a leap year.2000 2000 is a leap year.也可以将程序中判定闰年的if语句改写成以下if语句:if(year%4!=0)leap=0;else if(year%100!=0)leap=1;else if(year%400!=0)leap=0;else leap=1;也可以用一个逻辑表达式包含所有的闰年条件,将上述if语句用下面的if语句代替:if(year%4=0&year%100!=0)|(year%400=0)leap=1;e
29、lse leap=0;也可以用下面的条件运算符代替上面的if语句:(year%4=0&year%100!=0)|(year%400=0)?leap=1:leap=0;4.4 循环结构程序设计通过前面两节的学习,我们已经掌握了顺序结构、分支结构程序设计方法,本节我们继续学习另外一种程序设计方法循环结构。在很多实际问题中经常遇到具有规律性的重复运算,因此在程序中就需要将某些语句重复执行。一组重复执行的语句称为循环体,每一次重复都必须做出继续重复还是停止执行的决定,决定所依据的条件称为循环的控制条件。这种重复语句就是程序中的另一种重要的基本结构即循环结构。C语言中的重复语句有三种类型:for循环语句
30、、while循环语句和dowhile循环语句,另外还可以用转向语句goto和if语句实现循环控制。本节将给出各种循环语句的语法格式和使用方法。4.4.1goto语句构成的循环goto语句是一种使程序流程无条件转移的语句。其语法格式为:goto 标号;它的作用是从所在处,转向本函数内的某一处,程序必须指出转向的目的地,目的地用标号指明。标号应是合法的标识符,它的命名规则与变量名相同。在作为转向目标的语句的前面要用同一标识符作为标号。开始int i=1,sum=0i=100sum=sum+ii=i+1goto loop结束图4.15NYgoto语句通常与条件语句配合使用。可用来实现条件转移,构成循
31、环体,跳出循环体等功能。但是,在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。goto语句只在一个地方有使用价值:当要从多重循环深处直接跳转到循环之外时,如果用break语句,将要用多次,而且可读性也不好,此时goto可以发挥作用。开始int i=1,sum=0i=100sum=sum+ii=i+1goto loop结束图4.15NY例4.14求。本例用变量i表示待累加的变量的值,变量sum表示累加和,算法表示如下。S1:i1,sum0S2:如果i=100,则sum=sum+i,i=i+1,否则算法结束S3:返回S2,继续执行。传统流程图如图4
32、.15所示。据此写出源程序如下:#include void main()int i=1,sum=0;loop:if(i=100)sum=sum+i;i=i+1;goto loop;coutsum=sumendl;运行情况为:sum=5050本例用if语句和goto语句构成循环结构。如果i100则结束循环体,然后转移至goto后续语句执行。在这个程序中,变量i不仅表示了待累加的变量的值,而且还起着控制循环是否继续进行的作用。在很多计算机类的书籍中把起着控制循环继续进行否的变量称之为循环控制变量。本例整个执行过程中i,sum的变化过程如表4.1所示 循环次数循环控制变量ii=100的值循环体语句本
33、次循环后i的值本次循环后sum值0110111s=0+1;i=i+1;21221s=1+2;i=i+1;33331s=3+3;i=i+1;46441s=6+4;i=i+1;510551s=10+5;i=i+1;6151001001s=4950+100;i=i+1;10150501011010结束说明:(1)由此例可知,循环结构由三部分组成:初始化部分,循环体部分和循环控制部分。在初始化部分要完成循环体中所用到的相关变量的声明、定义初值等工作。如本例中的“int i=1,sum=0;”语句,一般在循环体前完成。在循环体部分完成需要重复执行的各步操作。如本例中求累加和、i增值、返回循环条件判断语句
34、处等操作,即以下语句:sum=sum+i;i=i+1;goto loop;循环控制部分用来给定控制循环是否继续执行的条件,如本例中的“loop:if(i100”,因此在循环体中应该有使i增值以最终导致i100的语句,本例中用“i=i+1;”语句来达到此目的。如果无此语句,则i的值始终不改变,循环永不结束。4.4.2while循环while语句用来实现“当型”循环结构。其一般形式如下:while(表达式)语句它的作用是当表达式为真(非0)时,执行while语句中的内嵌语句。其传统流程图、N-S图见图4.16所示。说明:(1)循环体如果包含一个以上的语句,应该用“”括起来,以复合语句形式出现,否则
35、while语句的范围只到while后面的第一个分号处。(2)在循环体中应 表达式语句假真当表达式为真 语句图4.16真i=1i100sum=sum+ii=i+1假面具i=1当i=100sum=sum+ii=i+1图4.17例4.15 求算法流程图如图4.17。据此算法写出源程序如下:#include void main()int i,sum=0;i=1;while(i=100)sum=sum+i;i=i+1;coutsumendl;运行情况为:5050本例用while循环结构。当i100时则结束循环体,然后转至后续语句执行。整个执行过程中i,sum的变化过程如表4.1所示。例4.16 打印指定
36、月份的日历。#include void main()int week,day,month,maxday,year,i;coutyearmonth;coutweekmaxday;coutn=year年month月=n;coutSUNtMONtTUEtWEDtTURtFRItSATn;i=0;while(iweek)/将该月份的第一天准确定位于所在的星期的位置coutt;i+;day=1;while(day=maxday)coutdayt;week=(week+1)%7;/此语句完成了使week+1的功能,同时模7,使产生/星期在06之间if(week=0)coutn;day+;4.4.3 dow
37、hile循环dowhile结构是另一种循环结构,其一般形式为:do 循环体语句while(表达式);它的作用是:先执行循环体语句,然后判别表达式,当表达式为真时,返回重新执行语句部分,如此反复,直到表达式的值为假为止,此时循环结束。其传统流程图、N-S流程图见图4.18所示。循环体语句表达式真假循环体语句 直到表达式为假图.18例4.17 求算法流程图如图4.19。据此算法写出源程序如下:#include void main()int i,sum=0;i=1;do sum=sum+i;i=i+1;while(i=100);coutsumendl;运行情况为:5050 i100sum=0 i=1
38、sum=sum+i i=i+1假真sum=0,i=1sum=sum+ii=i+1 当i=100图4.19本例用dowhile循环结构。当i100时则结束循环体,然后转至后续语句执行。整个执行过程中i,sum的变化过程如表4.1所示。说明:dowhile与while的比较(1)用dowhile语句时,至少要执行一次循环体。而while语句先判断(表达式)内的值,若为假,则跳出循环,因此可能循环体一次也不执行。(2)两个语句中的循环体基本相同。(3)循环变量初始化都在循环体前。(4)循环体语句中应该有使循环趋向于结束的语句。针对以上三点的比较,同学们在应用时可选择适合自己的结构,在此不再举例。4.
39、4.4 for循环C语言中的for语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况。其一般形式为:for(表达式1;表达式2;表达式3)循环体它的作用是:(1)先求解表达式1;(2)求解表达式2,若为0,则结束循环,转到(5);(3)若表达式2为真,执行循环体,然后求解表达式3;(4)转回(2);求解表达式1表达式2循环体求解表达式3for语句的下一语句假真求解表达式1当表达式2为真循环体求解表达式3图4.20(5)执行for语句下面的一个语句。其执行传统流程图、N-S流程图如图4.20所示。求解表达式1表达式2循环体求解表达式3for
40、语句的下一语句假真求解表达式1当表达式2为真循环体求解表达式3图4.20for语句最简单的应用形式也就是最易理解的形式:for(循环变量赋初值;循环条件;循环变量增值)语句例如:for(i=1;i=100;i+)sum=sum+i;它的执行过程与下列语句完全等价:i=1;while(i=100)sum=sum+i;i+;显然,用for语句简单、方便。对于以上for语句的一般形式也可以改写为while循环的形式:表达式1;while(表达式2)语句 表达式3;说明:(1)表达式1可以省略。此时应在for语句之前给循环变量赋初值。若省略表达式1,其后的分号不能省略。例如:i=1;sum=0;for
41、(;i100)break;(3)表达式3可以省略,但此时程序员应另外设法保证循环正常结束。例如:for(i=1;i=100;)sum=sum+i;i+;(4)表达式1和表达式3可同时省略。例如:for(;i100)break;(6)表达式1可以是设置循环变量初值的赋值表达式,也可以是与循环变量无关的其它表达式。例如:for(sum=0;i=100;i+)sum=sum+i;(7)表达式一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值为真,就执行循环体。例如:for(;ch1!=n;)coutcendl;从上面的介绍可知,for语句形式非常灵活,功能也非常强大,可以把循环
42、体和一些与循环控制无关的操作也作为表达式1或表达式3出现,这样程序可以短小简洁。但过分地利用这一点会使for语句显得杂乱,可读性降低,建议不要把与循环控制无关的内容放到for语句中,程序的可读性是我们追求的重要指标之一。例4.18 相传古代印度国王要褒奖他的聪明能干的宰相达依尔(国际象棋发明者),问他要什么?达依尔回答:“陛下只要在国际象棋棋盘的第一个格子上放一粒麦子,第二个格子上放二粒麦子,以后每个格子的麦子数都按前一格的两倍计算。如果陛下按此法给我64格的麦子,就感激不尽,其它什么也不要了。”国王想,“这还不容易!”让人扛了一袋麦子,但很快用光了,再扛出一袋还不够,请你为国王算一下共要给达
43、依尔多少麦子?(设1m3小麦约1.4108颗)算法N-S流程图如图4.21所示。ge=1.0,sum=1.0i=2i=64 ge=ge*2,sum=sum+ge i+输出sum图4.21据此算法写出源程序如下:#include void main()double ge=1.0,sum=1.0;int i;for(i=2;i=64;i+)ge=ge*2;sum=sum+ge;sum=sum/(1.4e8);coutThe weight is summ3endl;运行情况为:The weight is 1.31762e+011m3例4.19 用蒙特卡洛法求的近似值用蒙特卡洛法计算的近似值的基本思想
44、:蒙特卡洛法也称随机抽样技术或统计实验方法,是一种应用随机数进行仿真实验的方法。用蒙特卡洛方法计算的近似值的基本思想是:根据圆面积的公式:S=R2当R=1时,S=。由于圆的方程为:X2+Y2=1因此,1/4的圆面积为X轴、Y轴和上述方程所包围的部分。如图4.22所示,如果在11的矩形中均匀地落入随机点,则落入1/4圆中的点的概率就是1/4圆的面积。其4倍,就是圆面积。由于半径为1,该面积的值即的值。依据以上分析写出源程序如下:#include#include#include#define N 2000 /定义随机点void main()int n=0,i;float x,y;/坐标 srand
45、(time(00);for(i=1;i=N;i+)/在11的矩形中产生N个随机点x=rand()/RAND_MAX;/在0至1之间产生一个随机x坐标 y=rand()/RAND_MAX;/在0至1之间产生一个随机y坐标 if(x*x+y*y=1.0)n+;/统计落入单位圆中的点数 coutn The Pi is 4*(float)n/Nendl;/计算出的值运行情况为:The Pi is 44.4.5 循环的嵌套一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多层循环。C语言中的三种循环可以自身嵌套也可以互相嵌套。例如下面几种形式都是合法的形式:(1)
46、while()(2)while()while()do while();(3)do (4)for(;)do while()while();while();(5)for(;)(6)do for(;)for(;)while();图4.23假开始i1i6j1j5输入gj+求aver真真sum0sumsum+g输出一个学生的平均成绩i+假结束例4.20 一个班有6个学生,每个学生考5门课。要求分别统计出每个学生各门课的平均成绩。我们用双层循环来解决这个问题。外层循环用来处理6个学生,内层循环用来处理一个学生的5门课成绩,流程图见图4.23。#include void main()int i,j,g,su
47、m,aver;for(i=1;i=6;i+)sum=0;for(j=1;jg;sum=sum+g;aver=sum/5;coutNO:itaver=averendl;运算情况如下:65 67 87 98 89NO:1 aver=8187 65 54 83 91NO:2 aver=7674 83 92 53 81NO:3 aver=7698 12 65 86 97NO:4 aver=7112 48 98 90 57NO:5 aver=6178 68 56 39 71NO:6 aver=62说明:双重循环的执行过程是这样的:先执行外循环,当进入第一次外循环体时,外循环变量i的值为1,这个值在执行第
48、一次外循环全部过程中保持不变。图4.22中虚线框内是外循环体。在此范围内i值不变。由于外循环体包含一个内循环,因此在执行一次外循环体的过程中要执行5次内循环体。在执行第一次内循环体时,内循环变量j的值等于1,在执行完内循环体后,j的值变成2,在执行完第5次循环体后,j的值变成6,由于它超过了终值5,故内循环执行结束(注意此时j的值为6)。接着执行下面的语句,计算和输出一个学生的平均成绩。至此外循环体已执行完毕,外循环变量i的值变成2,然后开始第二次执行外循环体。请注意:内循环变量j重新取初值1(此时j的值已不再是6了,在每次遇到for语句时,循环变量都要重新取初值)。在第二次执行完外循环体时,
49、j=6,i变为3。在第三次进入外循环时,j又重新取值1,。一个学生的成绩在未进行累加前显然应该为0,在累加完一个学生的5门课成绩后,sum中已经存放了一个学生的总分了。所以在求第二个学生时,sum的初值应重新置为0,否则就会将第一个学生的总分全部加到第二个学生的成绩上,造成严重误差。因此必须保证在求每一个学生总分之前,sum的初值为0。例4.20 编程以左下三角的形式输出乘法的九九表。算法流程图如图4.24所示。据此算法写出源程序如下:#include void main()int i,j;for(i=1;i=9;i+)for(j=1;j=i;j+)coutj*i=j*i ;coutn;开始i
50、nt i,ji=1i9j=1ji输出j*ij+i+结束真真假假int i,ji=1i=9j=1j=i输出j*ij+i+图4.24外循环轮数i内循环控制表达式内循环轮数j输出一1j=1一11*1=1二2j=2一11*2=2 二22*2=4三3j=3一11*3=3 二22*3=6 三33*3=9四4j=4一11*4=4 二22*4=8 三33*4=12 四44*4=16五5j=5一11*5=5 二22*5=10 三33*5=15 四44*5=20 五55*5=25九9j=9一11*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81