项目3项目菜单的选择执行.ppt

上传人:小飞机 文档编号:4998543 上传时间:2023-05-28 格式:PPT 页数:80 大小:325KB
返回 下载 相关 举报
项目3项目菜单的选择执行.ppt_第1页
第1页 / 共80页
项目3项目菜单的选择执行.ppt_第2页
第2页 / 共80页
项目3项目菜单的选择执行.ppt_第3页
第3页 / 共80页
项目3项目菜单的选择执行.ppt_第4页
第4页 / 共80页
项目3项目菜单的选择执行.ppt_第5页
第5页 / 共80页
点击查看更多>>
资源描述

《项目3项目菜单的选择执行.ppt》由会员分享,可在线阅读,更多相关《项目3项目菜单的选择执行.ppt(80页珍藏版)》请在三一办公上搜索。

1、,项目3,项目菜单的选择执行,技能目标,会画程序的流程图或N-S结构图会用if-else实现分支结构和多分支结构的程序设计会用条件运算符进行分支结构的程序设计会用switch语句实现多分支结构的程序设计会用for语句、while语句、do-while语句进行循环结构程序设计会用break语句和continue语句,知识目标,掌握if-else语句的用法掌握条件运算符的使用掌握switch语句的用法掌握for语句、while语句和do-while语句的使用掌握循环的签套使用掌握break和continue语句的使用,项目任务与解析,本项目实现班级学生成绩管理系统中用if语句实现菜单的选择执行、用

2、switch语句实现菜单的选择执行、用循环语句实现主菜单的选择执行。本项目包含下面几个任务:任务4:用if语句实现菜单的选择执行 任务5:用switch语句实现菜单的选择执行 任务6:用循环语句实现主菜单的选择执行,主要内容,3.1 任务4:用if语句实现菜单的选择执行3.2 必备知识与理论3.3 扩展知识与理论3.4 任务5:用switch语句实现菜单的选择执行3.5 必备知识与理论3.6 扩展知识与理论3.7 任务6:用循环语句实现菜单的选择执行3.8 必备知识与理论3.9 扩展知识与理论,3.1 任务4:用if语句实现菜单的选择执行,1.问题描述对显示的菜单,选择要执行的菜单序号,并显示

3、要执行的菜单名。2.具体实现P41程序3.知识分析在多数情况下顺序结构的程序是很少的,一般还包括分支和循环结构。分支结构还包括if-else结构和switch结构。我们首先来学习分支结构,在学习分支结构前了解一些算法的概念,关系运算符和逻辑运算符的使用。,3.2必备知识与理论,3.2.1 算法的概念1.算法算法就是程序处理问题的步骤与方法。1976年瑞士计算机科学家Niklaus Wirth提出了一个著名的公式:算法+数据结构=程序,2.算法的特性 简单地说,算法就是进行操作的方法和操作步骤。例如,菜谱实际上是做菜肴的算法,乐谱实际上是演奏的算法,计算机程序是用某种程序设计语言描述的解题算法。

4、通常认为算法有如下一些性质:(1)有穷性 一个算法要在有限的步骤内解决问题(这里所说的步骤是指计算机执行步骤)。计算机程序不能无限地运行下去(甚至不能长时间地运行下去),所以一个无限执行的方法不能成为程序设计中的“算法”。(2)确定性 确定性具有两重意义:一是所描述的操作应当具有明确的意义,不应当有歧义性。例如,不能发出这样的操作指令:“执行一个算术操作”。因为它既没有指出算术操作的类型,也没有指出操作数。确定性的另一重意义:操作作序列只有一个初始动作,序列中每一动作仅有一个后继动作;序列终止表示问题得到解答或问题没有解答,不能没有任何结论。,(3)有零个或多个输入 输入就是从外界取得必要的信

5、息。一个算法可以有零个或多个输入,例如:输入一个年份,判断其是否是闰年。同时一个算法可以没有输入,例如:计算出5!是多少。(4)有一个或多个输出 算法的目的就求解,“解”就是我们想要得到的最终结果。输出是同输入有着某些特定关系的量。一个算法得到的最终结果就是输出。没有输出的算法是没有意义的。(5)可执行性一个算法应当是可以由计算机执行的,算法中描述的操作都是可以通过计算机的运行来实现。,3.2.2 算法的表示方法 1.自然语言表示算法 自然语言是相对于计算机语言而言的,是指人们在日常生活中使用的语言,如汉语、英语等。对于某些程序员来说,自然语言通俗易懂。但是,对于规模大、复杂的算法,使用自然语

6、言来描述,往往很冗长,不直观,而且容易发生歧义。比如对于以下这句话:如果A大于B,就给它加1。在理解时就可能出现歧义,是给A加1?还是给B加1。对于以上的一段话,如果我们用C语言进行编程则为:if(AB)A=A+1;正是由于自然语言描述算法具有的缺陷,所以在程序设计中很少有人使用。,2.传统流程图表示法 用一些图框表示各种操作,用线表示这些操作的执行顺序。我国国家标准GB 152689中推荐的一套流程图标准化符号,它与国际标准化组织ISO提出的ISO流程图符号是一致的。图3-1为其中常用的一些符号。,图3.2 常用的流程图标准化符号,平行四边形表示数据,其中可注明数据名称、来源、用途或其它的文

7、字说明。处理矩形表示各种处理功能。例如,执行一个或一组特定的操作,从而使信息的值、信息形式或所在位置发生变化。矩形内可注明处理名称或其简要功能。预定义过程带有双竖边线的矩形,表示已命名的处理。该处理为在另外地方已得到详细说明的一个操作或一组操作。例如库函数或其它已定义的函数等。矩形内可注明特定处理名称或其简要功能。判断菱形表示判断。菱形内可注明判断的条件。它只有一个入口,但可以有若干个可供选择的出口,在对定义的判断条件求值后,有一个且仅有一个出口被选择。求值结果可在表示出口路径的流线附近写出。流线直线表示执行的流程。当流程自上向下或由左向右时,流程线可不带箭头,其它情况应加箭头表示流程。端点。

8、扁圆形表示转向外部环境或从外部环境转入的端点符。例如,程序流程的起、始点。注解。注解是程序的编写者向阅读者提供的说明。注解符由纵边线构成,它用虚线连接到被注解的符号或符号组上。,图3-2(a)、(b)、(c)中的虚线框,分别为用流程图表示的三种基本流程控制结构。,(a)顺序结构,(b)选择结构,(c)重复结构,图3-2 用流程图描述的三种基本结构,例3-1 用流程图描述从三个数中取最大数的算法。从三个数中取最大数的算法思路是:假定这三个数是a,b,c,则首先可以比较a,b两数,从中选大者;然后再用这个大数与数c比较,从中取大者。这时得到的大数,就是三个数中的最大数。这个算法用流程图描述如图3-

9、3(a)所示。通常,求解一个问题的算法不是唯一的。例如图3-3(b)也是一个三数中取大的算法。它的基本思路是,先设max=第一个数,然后依次输入i个数,每输入一个数,与max比较一次,把大的放入max中。当输完i个数时,max中存放的就是这i个数中的最大数。这里,i是一个计数器,用于统计输入数的个数,所以每输入一个数,要执行一次自增操作。这个算法与图3-3(a)所示算法的不同在于:算法结构不同:图3-3(a)所示算法采用了两个选择结构,而图3-3(b)所示算法采用了一个循环结构和一个选择结构。算法的灵活性不同:图3-3(b)中的算法可以用来求任意个数中的最大数。,(a)一个三数中取大的算法,(

10、b)另一个三数中取大的算法,图3-3 三数中取大算法的流程图描述,3.用N-S流程图表示算法灵活的流线是程序中隐藏错误的祸根。针对这一弊病,1973年美国学者I.Nassi和B.Shneiderman提出了一种无流线的流程图,称为N-S图。它的三种基本结构如图3-4所示。N-S图的每一种基本结构都是一个矩形框,整个算法可以像堆积木一样堆成。其中,(a)为三个操作组成的顺序结构;(b)为二分支的选择结构;(c)为当型重复结构,即当命题P 为“真”时,就重复执行S。,(c)循环结构,(a)顺序结构,(b)选择结构,图3-4 用N-S图描述三种基本流程结构,图3-5(a)、(b)给出了用与图3-3(

11、a)、(b)流程图对应的N-S图。,(a)采用选择结构,(b)采用循环结构,图3-5 三数中取大算法的N-S图描述,3.用伪码表示算法伪代码(pseudo code)是用介于自然语言与计算机语言之间的文字符号算法描述的工具。它无固定的、严格的语法规则,通常是借助某种高级语言的控制结构,中间的操作可以用自然语言(如中文或英文),也可以用程序设计语言,或使用自然语言与程序设计语言的混合体。一般专业人员习惯用伪代码进行算法描述。下面是与图3-3相对应的三数中取大算法的伪代码描述。(1)与图3-3(a)相对应的三数中取大算法的伪代码描述:,输入a,b,c;if(a=b)max=a;else max=b

12、if(max=c)输出max;else 输出c;,(2)与图3-3(b)相对应的三数中取大算法的伪代码描述:,初始化:mac=0,i=1;当(i=max)max=n;)输出max;,3.2.3 结构化程序设计结构化程序设计的基本思路是:把一个复杂的问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解的范围之内。采取以下的方法保证得到结构化的程序:自顶向下;逐步细化(求精);模块化设计;结构化编码。,结构化程序具有如下的特征:一个程序单元由顺序、分支和循环这三种基本结构组成;一个大的程序由若干个不同功能的小模块组成;每一个小模块只有一个入口和一个出口;,3.2.4 命题与C语言中的逻

13、辑值对选择结构、循环结构,流程的改变都是由判断决定的,即需要根据判断决定选择,根据判断决定是否循环以及循环的结束。通常,判断是针对命题的“真”、“假”进行的。例如,下面是一些命题:(行驶中)前面的交通信号灯是红色的。今天下雨。ab。如果a不能被b整除。这些命题的值都只能是一个逻辑(布尔)值:“真”或“假”。早期的C语言不提供专门的逻辑(布尔)类型,规定用非0值表示“真”,用0值表示“假”。在C99中,增加了_Bool类型,并增加了头文件,在其中定义了宏bool、true和false,用true存储1,用false存储0。,3.2.5 关系运算与关系表达式 1.C语言的关系运算符关系运算是指对两

14、个表达式值的大小比较。C语言中提供有如下6个关系运算符:(大于)=(大于或等于)(小于)=(小于或等于)=(等于)!=(不等于)后两个(=和!=)的优先级小于前4个,但它们都低于算术运算符,高于赋值运算符,并且它们结合方式都是从左向右的。,2.关系表达式用关系运算符将两个表达式(可以是算术表达式、关系表达式,逻辑表达式,赋值表达式,字符表达式等)连接起来的表达式,称为关系表达式。关系表达式的值只有两个:关系表达式成立,即为“真”(通常为1);关系表达式不成立,即为“假”(0)。,3.2.6 逻辑运算与逻辑表达式1.逻辑运算符与优先级 C语言有三个逻辑运算符,它们是:&(逻辑与)|(逻辑或)!(

15、逻辑非)&和|是二元运算符,结合方向为自左至右;!为一元运算符,结合方向为自右至左。!的优先级高于&,&的优先级高于|。&和|的优先级低于关系运算符,而!的优先级高于关系运算符。2.逻辑表达式 用逻辑运算符将关系表达式或逻辑量连接起来的表达式就 是逻辑表达式,逻辑表达式的值应该是一个逻辑量“真”或“假”。,逻辑运算中有很多有趣的规律,这种规律称为短路原则。1.在一个&表达式中,若&的一端为0,则不必再计算另一端,该表达式的值肯定为0(在C语言中由于&是从左向右结合的,所以只考虑左端,即当&号的左端为0时,不再计算其右端),可以把它记为:0&a=02.在一个|表达式中,若|的一端为1,则不必计算

16、另一端,该|表达式的值必为1。现把它记为:1|a=1 诸如此类关于表达式的值的规律有如下一些:0|a=a1&a=a1|a=10&a=0 a|!a=1 0&!a=0 以及 a|a=aa&a=a!(a|b)=!a&!b!(a&b)=!a|!b!(!a)=a记住这些规律,能使复杂的逻辑运算简化、清晰。,3.3 扩展知识与理论,选择型程序描述了求解规则:在不同的条件下所应进行的相应操作。3.3.1 if(表达式)语句这种语句的结构是:if(表达式)语句它的执行流程是,当表达式的值为真时,执行“语句”,否则执行if语句后面的语句。,例3-4 输入三个数a,b,c,要求按由小到大的顺序输出。我们只要把最小

17、的数放到a上:先将a与b进行比较,如果ab则将a与b的值进行交换,然后再用a与c进行比较,如果ac则将a与c的值进行交换,这样能使a最小。对剩下的两个数,从小到大排序就容易了,该程序的N-S结构图如右图所示。,3.3.2 ifelse结构 ifelse构造了一种二路分支的选择结构,它的格式如下:if(表达式)语句1 else 语句2 这里,语句1和语句2就是两路分支。执行这个结构,首先对表达式进行判断,若为“真”(非零),就执行if分结构(语句1);否则(值为0),就执行else分结构(语句2)。,例3-5 求一个数的绝对值。设有任意数x,它的绝对值为 判断内容:x0是否成立。两路分支:x=x

18、(当x0);x=-x(当x0)C函数如下:,double abstr(double x)if(x0.0)x=-x;else x=x;return(x);,下面是函数abstr被调用执行的情况:,#include int main(void)double a,abstr(double a);printf(Enter real number a please:);scanf(%1f,运行情况如下,Enter real number a please:-98.7654 abstr(-98.765400)=98.765400,例3-6 求一元二次方程ax2+bx+c=0的根。算法设计:一元二次方程式的

19、根有下列情况:当a=0,b=0时,方程无解;当a=0,b0时,方程只有一个实根-c/b;当a0时,方程的根为x=(-b(b2-4ac)1/2)/(2*a)。其中,当b2-4ac0时有两个实根;当b2-4ac0时,有两个虚根。图3-8为上述算法的N-S图表示,它把上述逻辑关系表示得更为清晰。,图3-12 求一元二次方程根的算法,include void solv_quadr_equa(float a,float b,float c)if(a=0.0)if(b=0.0)printf(no answer due to input errorn);else printf(the single root

20、 is%fn,-c/b);else double disc,twoa,term1,term2;disc=b*b-4*a*c;twoa=2*a;term1=-b/twoa;term2=sqrt(fabs(disc)/twoa;if(disc0.0 printf(complex root:n real part=%f,imag part=%fn,term1,term2);else printf(real root:n root1=%f,root2=%fn,term1+term2,term1-term2);,由此N-S图可以编写出以下的函数:,3.3.3 if-else if结构if-else if

21、是一种多分支选择结构,用N-S图描述下右图所示,C语言中的格式如下左图所示:,if(表达式1)语句1else if(表达式2)语句2else if(表达式n)语句nelse 语句n+1,例3-7 根据百分制分数决定成绩的等级:90分以上为A级;80分及以上,90分以下,B级;70分及以上,80分以下,C级;60分及以上,70分以下,D级;60分以下,E级。下图为用if-else if结构描述的上述规则。,3.4 任务5:用switch语句实现菜单的选择执行,1.问题描述对显示的菜单,选择要执行的菜单序号,并显示要执行的菜单名。2.具体实现P54程序3.知识分析分支结构程序设计除if-else结

22、构外,还包括switch结构。Switch结构是一种多路分支的选择结构程序设计。,switch是一种多分支选择结构,其形式如下图左所示,N-S结构图如下右图所示。,3.5 必备知识与理论,switch(表达式)case 常量表达式1:语句序列1 case 常量表达式2:语句序列2 case 常量表达式n:语句序列n default:语句序列n+1,这里,break语句的作用是中断该switch结构,即将流程转出switch结构。所以,执行switch结构的就相当于只执行与判断表达式相匹配的一个case子结构中的语句。其实,可以将break看作为语句序列中必要的成分(位置在语句序列中的最后)。,

23、switch(表达式)case 常量表达式1:语句序列1 break;case 常量表达式2:语句序列2 break;case 常量表达式n:语句序列n break;default:语句序列n+1 break;,例3-11 根据百分制分数决定成绩的等级:90分以上为A级;80分及以上,90分以下,B级;70分及以上,80分以下,C级;60分及以上,70分以下,D级;60分以下,D级。,/*按成绩分等*/#include int main(void)float score;int grade;printf(输入一个分数:);scanf(%f,3.6 必备知识与理论,条件运算符是C语言中唯一的三目

24、运算符,即有三个参数参与运算。由条件运算符组成条件表达式的一般形式为:表达式1?表达式2:表达式3 其求值规则为:如果表达式1的值为真,则把表达式2的值作为该条件表达式的值,否则把表达式3的值作为该条件表达式的值。条件运算符的优先级很低,仅仅比赋值操作符的级别高。其结合方式与赋值运算符一样是从右至左的。因此,表达式max=ab?ab相当于:max=(ab?a:b);,3.6 扩展知识与理论,3.7 任务6:用循环语句实现菜单的选择执行,1.问题描述对显示的菜单,选择要执行的菜单序号,并显示要执行的菜单名。2.具体实现用for语句实现P60程序用while语句实现P61程序用dowhile语句实

25、现P61-P62程序3.知识分析循环结构程序设计包括while、do-while和for循环三种结构,对已知循环次数的循环多采用for循环;对循环次数不确定,循环首先执行一次的循环多采用do-while循环,而需要根据循环条件来确定循环是否要执行的,多采用while循环。,3.8 必备知识与理论,3.8.1 while结构while语句的一般形式为:while(表达式)语句其中表达式是循环条件,语句为循环体。while语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句;否则跳过循环体,而执行该结构后面的语句。在进入循环体后,每执行完一次循环体语句后,再对判断表达式进行一次计算和判

26、断。当发现判断表达式的值为0时,便立即退出循环。,例3-12 兔子繁殖问题。著名意大利数学家Fibonacci曾提出一个有趣的问题:设有一对新生兔子,从第三个月开始它们每个月都生一对兔子。按此规律,并假设没有兔子死亡,一年后共有多少对兔子。人们发现每月的兔子数组成如下数列:1,1,2,3,5,8,13,21,34,并把它称为Fibonacci数列。那么,这个数列如何导出呢?观察一下Fibonacci数列可以发现这样一个规律:从第3个数开始,每一个数都是其前面两个相邻数之和。这是因为,在没有兔子死亡的情况下,每个月的兔子数由两部分组成:上一月的老兔子数,这一月刚生下的新兔子数。上一月的老兔子数即

27、其前一个数。这一月刚生下的新兔子数恰好为上上月的兔子数。因为上一月的兔子中还有一部分到这个月还不能生小兔子,只有上上月已有的兔子才能每对生一对小兔子。,上述算法可以描述为 fib1=fib2=1(1)fibn=fibn-1+fibn-2(n=3)(2)式(1)为赋初值,式(2)为迭代公式。用C语言来描述式(2)为:,fib=fib1+fib2;fib1=fib2;/*为下一次迭代作准备*/fib2=fib;,这里,fib1和fib2和不再仅代表第1个月和第2个月的兔子数,而作为中间变量,代表前两个月的兔子数,fib当前月的兔子数。下页图为Fibonacci算法的N-S图。表为迭代过程中fib1

28、、fib2和fib的变化情形。,图3-12 计算Fiboonacci数列的N-S图,表 按照迭代算法变量fib1、fib2和fib3的变化情形,根据图3-12所示的算法。可以很容易地写出如下程序。,/*计算Fibonacci数*/#include int main(void)int fib1=1,fib2=1,fib,i=3;while(i=12)fib=fib1+fib2;fib1=fib2;fib2=fib;i+;printf(“The Fibonacci number after 1 yer is:%dn”,fib);return 0;,例3-13 百钱买百鸡问题。公元前五世纪,我国古代

29、数学家张丘建在算经一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、母、雏各几何?(1)基本解题思路 这是一个有名的不定方程问题:,cocks+hens+chicks=100(1)5*cocks+3*hens+chicks/3=100(2),式中:cocks:鸡翁数hens:鸡母数chicks:鸡雏数,对上述不定方程问题,要先确定一个变量的值,才能对其进行求解。由问题中给出的条件,很容易得到三个变量的取值范围:,cocks:019中的整数(因为每只鸡翁5钱,因此它不可能超过19只)hens:033中的整数chicks:0100中的整数,基本的解题思路是:依

30、次取cocks值域中的一个值,然后求其余两数,看是否合乎题意,合乎者为解。这个基本解题思路便是解本题的粗略算法,下面是它的伪代码描述,图3-13(1)为其N-S图。,s1:cocks=0;/*赋初值*/s2:当(cocks=19)s2.1:找满足题意的hens,chicks;s2.2:cocks+;S3:输出一组cocks,hens和chichs,图3-13(1)百钱买百鸡的粗略算法,(2)对s2.1细化思路1:把已确定的cocks代入式(1)与(2)中,求解方程,看能否找到满足题意的解。这种思路不太适合计算机求解。思路2:在每个给定的cocks下,面对hens的取值范围内的各个值依次测试,看

31、能找到哪些hens及chicks满足题意。于是得到如下s2.1细化算法。,用这段算法代替图3-13(1)中的“找满足题意的hens和chicks”,得到图3-13(2)所示的百钱买百鸡的N-S图算法。,s2.1.1:hens=0;s2.1.2:当(hens=33)s2.1.2.1:找满足题意的chicks;s2.1.2.2:hens+;/*即hens=hens+1*/,图3-13(2)百钱买百鸡算法的细化算法,(3)对细化 对来说,cocks及hens都已确定,这时的chicks可以计算出:chicks=100-cocks-hens 式(1)已满足。只要用式(2)指定的条件测试便可知这一组co

32、cks,hens及chicks是否满足题意。满足则打印出一组解。于是可细化为:,图3.13(3)为进一步细化的百钱买百鸡算法。,s2.1.2.1:chicks=100-cocks-hens;if(5*cocks+3*hens+chicks/3.0)=100)printf(%d%d%dn,cocks,hens,chicks);,图3-13(3)百钱买百鸡算法的细化算法,/*百钱买百鸡问题*/#include int main(void)int cocks=0;printf(%8s%8s%8sn,cocks,hens,chicks);while(cocks=19)int hens=0;while(

33、hens=33)int chicks;chicks=100-cocks-hens;if(5*cocks+3*hens+chicks/3.0=100)printf(%8d%8d%8dn,cocks,hens,chicks);hens+;cocks+;return 0;,3.8.2 dowhile结构 dowhile,其形式如下:,当流程到达do后,立即执行循环体一次,然后才对判断表达式进行计算、测试。若表达式的值为真(非0),则重复执行一次循环体;否则退出。与while结构相比,dowhile结构至少要执行一次循环体。这样的结构应用在需要事先执行一次循环体的程序非常容易理解。,do 循环体whi

34、le(表达式);,例3-14 用牛顿迭代法计算一个正实数a的平方根,精确到E0=10-5。(1)建立迭代关系式,由题意可以写出:x=(a)1/2 或 x2=a 于是得到方程:f(x)=x2-a=0,f(x)=2x 根据牛顿迭代公式 x=x-f(x)/f(x)=x-(x2-a)/2x=1/2(x+a/x)即 x=(x+a/x)*0.5 这就是要建立的迭代关系式。,(2)给定初值。今设a的初值为a(当然也可以为其它值)。(3)给定精度(误差)为E0。精度是迭代控制的条件,当误差大于E0时,要继续迭代。如何计算误差呢?本来应该用x-a来表示误差,即把求出的x与真正的a相比,计算出其误差,但是现在a并

35、不知道,因此可换一种方法来表示误差,用x*x-a(因为要求x=a,即x2=a,x与a的差距可以通过x2与a的差距反映出来)。于是得到循环结构的控制条件:x2-aE0 即 fabs(x*x-a)=E0,/*计算平方根*/#include#define E0 0.00005double sq_root(double a)/*计算a的平方根*/double x;x=a;x=(x+a/x)*0.5;while(fabs(x*x-a)=E0)x=(x+a/x)*0.5;return(x);,这里fabs是一个标准数学函数名。E0是误差要求,可以用define命令在程序头部作为一个符号常数进行定义,在不同

36、情况下根据需要可以对它修改。,#include int main(void)double f=2.0;printf(The root of%f is%fn,f,sq_root(f);return 0;,用下面的主函数进行测试,测试结果如下:,The root of 2.000000 is 1.414216,3.8.3 for结构 为了说明for结构,先看下面一个程序段:,sum=0;for(i=1;i=n;i+)sum=sum+i;,它是下面的控制结构的一个例子。,for(表达式1;表达式2;表达式3)循环体,为了说明for后面括弧中三个表达式的语句,将它改写为如下while结构:,sum=0

37、;i=1;/*相当于for语句中的表达式1*/while(i=n)/*相当于for语句中的表达式2*/sum=sum+i;/*for循环体*/i+;/*相当于for语句中的表达式3*/,显然,这三个表达式的作用是控制循环,故称循环控制表达式。表达式1称为初始化表达式;表达式2称为条件表达式;表达式3称为修正表达式。可以看出:for语句是将初始化、条件判断、循环变量值变化三者组织在一起的循环控制结构。for结构的格式可以表示为:,for语句的执行过程如下:(1)先执行表达式1(初始化表达式)。注意在整个循环中它只执行一次。(2)重复下面的过程:计算表达式2(判断表达式),若为真(非0),就执行一

38、次循环体语句,然后再执行表达式3(修正表达式);再计算表达式2(判断表达式),判断是否为“真”,直至表达式2(判断表达式)的值为假(0),就不再执行循环体了。,for(初始化表达式;判断表达式;修正表达式)循环体语句,在某些情况下,用for结构表示循环,显得紧凑而清晰。尤其是它能利用表达式3自动地使循环变量值发生改变,不像while结构那样要在循环体中设置“修正操作”。实际上,for语句中的表达式3并不仅限于修正循环变量,而可以是任何操作。例如前面介绍的求1+2+n的程序段可以改写为:,形成一个没有循环体的结构,或者说循环体是一个空语句(仅一个分号)。而表达式3成为一个逗号表达式,它包含两个简

39、单表达式(包含了本应由循环体完成的功能),表达式的执行顺序从左到右。表达式1也是一个逗号表达式,它使sum和i都初始化。,for(sum=0,i=1;i=n;sum=sum+i,i+);,计算Fibonacci数程序,用for结构修改如下:#include int main(void)int fib1=1,fib2=1,fib,i;for(i=3;i=12;i+)fib=fib1+fib2;fib1=fib2;fib2=fib;printf(“The Fibonacci number after 1 yer is:%dn”,fib);return 0;,百钱买百鸡问题用for结构编写的程序如下

40、:#include int main(void)int cocks;printf(%8s%8s%8sn,cocks,hens,chicks);for(cocks=0;cocks=19;cocks+)int hens;for(hens=0;hens=33;hens+)int chicks;chicks=100-cocks-hens;if(5*cocks+3*hens+chicks/3.0=100)printf(%8d%8d%8dn,cocks,hens,chicks);return 0;,例3-18 打印九九表。,下面用逐步求精的方法分析本例的解法。表体共九行,所以首先考虑一个打印九行的算法s1

41、:下面进一步考虑如何“打印第i行”。因为每行都有九个数字,故“打印第i行”可以写为s1.1:,for(i=1;i=9;i+)打印第i行 打印换行符,for(j=1,j=9;j+)打印第j个数,“打印第j个数”即在第i行的第j列上打印一个数,大小为i*j,占4个字宽。故可写为,printf(%4d,i*j);,在写这个语句时,人们自然要考虑写不写换行符。显然不能在每个数字后面都换行,而只能在第9个数字后面写换行。实现只在第9个数字后面换行的办法是,打印完一行,即在j循环后写一个语句使换行:,printf(n);,于是,打印九九表的程序可写为:,/*打印九九乘法表*/#include int ma

42、in(void)int i,j;for(i=1;i=9;i+)/*实际上将9改为i,更符合数学上的习惯*/for(j=1;j=9;j+)printf(“%d*%d=%4d,i,j,i*j);printf(n);return 0;,例3-19 用梯形法求数值积分。定积分的几何意义就是求曲线f(x)与直线y=0,x=a,x=b所围成的曲顶梯形的面积。当能找到f(x)的原函数F(x)时,利用牛顿-莱布尼兹公式:可以精确地求出I值来。当f(x)的原函数不易找到时,便可以借助数值方法近似地求出I的值。用数值方法计算定积分有两个关键:一是将连续的对象分割为容易求解的一些子对象;二是用迭代法对迭代表达式反复

43、操作。下面介绍一种容易理解的方法梯形法。由图3-16所示,一个曲顶梯形可以分割为许多小的宽为h的曲顶梯形。,图3-16 用梯形法求定积分,当h(h=(b-a)/n)很小时,每个小的曲顶梯形都可以近似看作是梯形,第i个小曲顶梯形的面积近似为:si=h/2f(a+ih)+f(a+(i+1)h)于是定积分的值(曲线所围成的面积):当n时,就能准确地求出定积分S。在现实中,只要取相当大的n,使误差小于要求的值,就可以近似地计算出定积分S。用迭代形式描述为:for(i=1;i=n-1;i+)s=0.5*h*(f(a)+f(b)s=s+h*f(a+i*h)最后计算的结果,就是函数f(x)的定积分。,下面是

44、一个利用梯形法求函数f(x)=4-x的定积分的程序:/*用梯形法求积分*/#include double f(double x);int main(void)float a,b;double s,h;int n,i;printf(输入计算的区间a,b);scanf(%f,%f,循环结构的中途退出与重复周期的中途结束下页图为循环结构中途退出(loop-and-half)与一个循环周期的中途结束的示意图。中途退出循环结构就是使用break语句,将流程转到该循环结构的后面。循环周期的的中途结束就是在重复执行到某一个循环周期的中间时,由于某种条件,不需要再执行循环体中后面的语句,提前结束该周期,而进入

45、下一循环周期,在C语言中需要使用continue实现。这两种控制功能不仅用于while结构中,也可以用在dowhile和for重复结构中。,3.9 扩展知识与理论,(a)循环结构中途退出,(b)一个循环周期的中途退出,3.9.1 中途退出循环结构break语句 break语句将流程转出switch结构。break语句还可以将流程中途转出任何一种循环结构。例3-20 验证素数。验证一个正整数n3的数是否为素数,一个最直观的方法是,看在2n/2中能否找到一个整数m能将n整除。若m存在,则n不是素数;若找不到m,则n为素数。这是一个穷举验证算法。这个循环结构用下列表达式控制:初值:m=2 循环条件:

46、m=n/2 修正:m+即这是一个for结构。它的作用是穷举2n/2中的各m值。循环体是判断n是否可以被m整除。显然,在这个过程中,一旦找到一个m可以整除n,则用该m后面的各数去验证已经没有意义了,需要退出循环结构。,按上述分析可以写出一个验证正整数n是否为素数的函数:,/*验证素数*/#include int main(void)int m,n,flag=1;printf(请输入要测试的整数:);scanf(%d,3.9.2 提前结束一个循环周期continue语句例3-21 输出100200间的所有素数。这个程序可以在例3.20的基础上进行。当测试到某个n存在一个因数m时,用break跳出内

47、层循环复结构,同时在外层循环结构中要跳过输出语句,进入对下一个数的测试。按上述分析可以写出一个验证正整数n是否为素数的函数:,/*输出素数*/#include int main(void)int m,n,flag;printf(nThe primers from 100 to 200 is:n);for(n=101;n=200;n+=2)/*仅测试100200间的奇数*/flag=1;/*设置标志*/for(m=2;m=n/2;m+)if(n%m=0)flag=0;/*改变标志*/break;/*跳出内层循环结构*/if(flag=0)/*判断标志*/continue;/*跳出过输出语句进入下一周期*/printf(“%d,”,n);printf(n);return 0;,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号