ok第二章第二章 基本控制结构程序设计基本控制结构程序设计结构化程序设计的特点是任何程序都可由结构化程序设计的特点是任何程序都可由三种基本结构三种基本结构及其组合来描述及其组合来描述本章将介绍本章将介绍C+分支结构和循环结构的设分支结构和循环结构的设计方法还将介绍一些计方法还将介绍一些常用算法常用算法ok第二章第二章 基本控制结构程序设计基本控制结构程序设计ok2.1.1 算算 法法 的的 概概 念念 2.1.3 算算 法描述的三种基本结构法描述的三种基本结构2.1.2 算算 法法 的的 表表 示示ok2.1.1 算算 法法 的的 概概 念念 算法:算法:算法是解决问题的步骤算法是解决问题的步骤计算机算法的特征:计算机算法的特征:(1)(1)可执行性可执行性(2)(2)确定性确定性(3)(3)有穷性有穷性(4)(4)可输入输出信息可输入输出信息算法是程序设计学习的重点算法是程序设计学习的重点ok2.1.2算法的表示算法的表示流程图:流程图:流程图是图形化的表示方法,比较直观,基本流程图是图形化的表示方法,比较直观,基本组成元件包括矩形框、菱形框、箭头线等其组成元件包括矩形框、菱形框、箭头线等。
其中矩形框表示要执行的指令,在框内标注指令中矩形框表示要执行的指令,在框内标注指令内容;菱形框表示要判断其中表达式的值是真内容;菱形框表示要判断其中表达式的值是真还是假;箭头线则标示指令的流程方向还是假;箭头线则标示指令的流程方向伪码:伪码:伪码是介于自然语言和程序设计语言之间的一伪码是介于自然语言和程序设计语言之间的一种类自然语言的表示方法,书写形式自由,容种类自然语言的表示方法,书写形式自由,容易转换为程序易转换为程序ok2.1.2算法的表示算法的表示活动图活动图:UMLUML活动图(活动图(activity diagramactivity diagram)用于计算流程和工作)用于计算流程和工作流程建模通常使用活动图来表达顺序程序的流程,这流程建模通常使用活动图来表达顺序程序的流程,这点与传统的流程图很相似,仅仅图示方法上有所不同点与传统的流程图很相似,仅仅图示方法上有所不同活动图要素:活动图要素:1 1)活动(活动(activityactivity):用一个上下为直线两侧为圆弧:用一个上下为直线两侧为圆弧的框表示,并在框内写明活动的名称的框表示,并在框内写明活动的名称2 2)转移(转移(transitiontransition):采用箭头表示。
采用箭头表示3 3)分支(分支(branchbranch):采用菱形符号采用菱形符号4 4)注解(注解(notenote):采用右上角折叠的矩形表示,说明:采用右上角折叠的矩形表示,说明UMLUML图中符号的意义,它与被说明的符号间用虚线连接图中符号的意义,它与被说明的符号间用虚线连接5 5)起点:起点:起始标志,采用黑色实心圆点表示起始标志,采用黑色实心圆点表示6 6)终点:终点:结束标志,采用实心的小同心圆表示结束标志,采用实心的小同心圆表示ok2.1.3算法描述的三种基本结构算法描述的三种基本结构3 循循 环环 结结 构构1 顺顺 序序 结结 构构2 分分 支支 结结 构构算法的基本结构:算法的基本结构:对算法的理论研究和实践表明,任何算法的描述对算法的理论研究和实践表明,任何算法的描述都可以分解为三种基本结构或它们的组合,这三都可以分解为三种基本结构或它们的组合,这三种基本结构是种基本结构是顺序结构顺序结构、分支结构分支结构和和循环结构循环结构oknum115;2.1.3算法描述的三种基本结构算法描述的三种基本结构(1)顺序结构顺序结构【例【例2 21 1】求两求两数之和寄存器35显示结果:显示结果:35 num115 num220 sum35num220;sumnum1+num2;演示算法执行过程演示算法执行过程输出输出sum;活动图ok2.1.3算法描述的三种基本结构算法描述的三种基本结构(2)分支结构分支结构【例【例22】输入三个数,输出其中的输入三个数,输出其中的最大数。
最大数x7;y12;z10;if(xy)maxx;else max y;if(zmax)maxz;输出输出max;x7y12z10CPUmax12比较比较比较比较显示结果:显示结果:12演示算法执行过程演示算法执行过程ok2.1.3算法描述的三种基本结构算法描述的三种基本结构【例【例2 23 3】求】求4 4个整数的和个整数的和0sum4count12x显示结果:显示结果:60演示算法执行过程演示算法执行过程123142621642118600count4;/整数个数整数个数sum0;/累加和的初值累加和的初值while(count0)x输入一个整数输入一个整数;s u m s u m+x;countcount-1;输出输出sum;ok2.2 分支结构程序设计分支结构程序设计 对程序的运行流程进行控制,主要通过执行对程序的运行流程进行控制,主要通过执行专门用来控制流程的语句来实现专门用来控制流程的语句来实现分支语句分支语句是基本流程控制语句之一是基本流程控制语句之一C+C+提供提供三种分支语句三种分支语句2.2.1 if语句语句 2.2.2 if语句的嵌套语句的嵌套 2.2.4 swich语句语句 2.2.3 条件运算符条件运算符“?:”?:”ok2.2.1 if 语句语句ifif语句基本格式:语句基本格式:1、if(表达式表达式)语句语句1;2、if(表达式表达式)语句语句1;else语句语句2;【例例2.4】输入一个年份,判断是否闰年。
输入一个年份,判断是否闰年例【例2.5】从键盘上输入三个整数,输出从键盘上输入三个整数,输出其中的最大数其中的最大数ok嵌套嵌套ifif语句:语句:if if 语句中,如果内嵌语句又是语句中,如果内嵌语句又是ifif语句,就构成了语句,就构成了嵌套嵌套ifif语语句句if if 语句可实现语句可实现二选一二选一分支,而嵌套分支,而嵌套ifif语句则可以实现语句则可以实现多选一多选一的多路分支情况的多路分支情况嵌套有两种形式,嵌套在嵌套有两种形式,嵌套在elseelse分支中分支中:if(表达式表达式1)语句语句1;else if(表达式表达式2)语句语句2;else if else 语句语句n;嵌套在嵌套在ifif分支中:分支中:if if()1)ifif()1;elseelse;2;2.2.2 if 语句的嵌套语句的嵌套【例【例2.6】用嵌套用嵌套if语句完成【例语句完成【例2.5】的任务okelseelse和和ifif的配对关系:的配对关系:C+C+规定了规定了ifif和和elseelse的的“就近配对就近配对”原则,即相距最近原则,即相距最近且还没有配对的一对且还没有配对的一对ifif和和elseelse首先配对。
首先配对按上述规定,第按上述规定,第二种嵌套形式中的二种嵌套形式中的elseelse应与第二个应与第二个ifif配对如果根据程序配对如果根据程序的逻辑需要改变配对关系,则要将属于同一层的语句放在的逻辑需要改变配对关系,则要将属于同一层的语句放在一对一对“”中如第二种嵌套形式中,要让中如第二种嵌套形式中,要让elseelse和第一个和第一个ifif配对,语句必须写成:配对,语句必须写成:ifif(表达式表达式1)1)if if(表达式表达式2)2)语句语句1;1;else else 语句语句2;2;第二种嵌套形式较容易产生逻辑错误,而第一种形式第二种嵌套形式较容易产生逻辑错误,而第一种形式配对关系则非常明确,因此从程序可读性角度出发,配对关系则非常明确,因此从程序可读性角度出发,建议建议尽量使用第一种嵌套形式尽量使用第一种嵌套形式2.2.2 if 语句的嵌套语句的嵌套ok配对关系实例:配对关系实例:/语句语句1 1:ifif(n%3=0)(n%3=0)ifif(n%5=0)cout(n%5=0)coutnn是是1515的倍数的倍数endlendl;else else cout cout n n是是3 3的倍数但不是的倍数但不是5 5的倍数的倍数 endl endl;/语句语句2 2:ifif(n%3=0)(n%3=0)ifif(n%5=0)cout(n%5=0)coutnn是是1515的倍数的倍数endlendl;elseelse cout cout n n 不是不是3 3的倍数的倍数两个语句的差别只在于一个两个语句的差别只在于一个“”,但表达的逻辑关系却,但表达的逻辑关系却完全不同。
完全不同例【例2.72.7】某商场购物优惠活动某商场购物优惠活动【例【例2.82.8】求一元二次方程的根求一元二次方程的根ok2.2.3 条件运算符条件运算符“?:”三元运算符:三元运算符:三元运算符条件运算符三元运算符条件运算符“?:”?:”可以用来简化可以用来简化ifif语句表达其语句表达其构成的表达式格式为:构成的表达式格式为:表达式表达式1?1?表达式表达式2:2:表达式表达式3 3例如:例如:intint a=6,b=7;min=ab?a:b;a=6,b=7;min=ab?a:b;/min=6/min=6 min=ab?+a:+b;min=ab?+a:+b;/min=7 a=7 b=7/min=7 a=7 b=7 min=ab?a+:b+;min=ascore;switch(score)case A:case a:coutexcellent;break;case B:case b:coutgood;break;default:coutfair;okok【例【例2.9】运输货物实行运输货物实行分分段计费段计费采用不采用不带带breakbreak的的开开关语句实例关语句实例 2.2.4 switch语句语句ok循环控制语句循环控制语句是基本流程控制语句之一。
是基本流程控制语句之一C+C+提供三种循环语句:提供三种循环语句:2.3.1 while语句语句 2.3.4 循环的嵌套循环的嵌套 2.3.3 for语句语句 2.3.2 do-while 语句语句 2.3 循环结构程序设计循环结构程序设计ok2.3.1 while 语句语句whilewhile语句也称为当循环语句也称为当循环语句格式为:语句格式为:while(while(表达式表达式)循环体语句;循环体语句;【例【例2.11】求求1+2+3+4+100的值ok2.3.1 while 语句语句注意:注意:在有循环语句的程序中,通常循环开始前对循环条件进在有循环语句的程序中,通常循环开始前对循环条件进行初始化;而在循环体语句中要包含修改循环条件的行初始化;而在循环体语句中要包含修改循环条件的语句,否则循环将不能终止而陷入死循环语句,否则循环将不能终止而陷入死循环C+表达方式灵活,例表达方式灵活,例2.11中的循环语句还可以写成:中的循环语句还可以写成:while(i=n)sum+=i+;或者或者while(sum+=i+,i=n);/循环体为空语句循环体为空语句这两种表达方式与例这两种表达方式与例2.11中的循环语句从执行结果看是完中的循环语句从执行结果看是完全等价的。
需要说明的是,虽然全等价的需要说明的是,虽然C+可以让代码最大可以让代码最大限度优化,但往往造成可读性降低,因此程序设计者限度优化,但往往造成可读性降低,因此程序设计者只需理解这种表达方法的意义,而设计时主要追求的只需理解这种表达方法的意义,而设计时主要追求的目标应是目标应是可读性可读性ok2.3.2 do-while 语句语句 do-while语句称为语句称为直到直到循环循环,格式为:,格式为:do 循环体语句循环体语句 while(表达式表达式)ok2.3.2 do-while 语句语句 do/while语句和语句和while语句的区别:语句的区别:do/while语句至少执行一次循环体后再判断语句至少执行一次循环体后再判断循环条件是否满足;循环条件是否满足;while语句先判断条件是否满足,然后才执行语句先判断条件是否满足,然后才执行循环体可能一次也不执行可能一次也不执行多数情况下可以互相替代多数情况下可以互相替代例【例2.12】用迭代法求用迭代法求a的平方根近似值的平方根近似值例【例2.13】输入一段文本,统计文本的输入一段文本,统计文本的行数、单词数及字符数行数、单词数及字符数。
ok2.3.3 for 语句语句 for循环语句的格式:循环语句的格式:for(表达式表达式1;表达式表达式2;表达式表达式3 )循环体语句循环体语句 ok执行过程为:先求表达式1的值,再求表达式2的值,判断表达式2的值,如果为真,则执行循环体语句,之后求表达式3的值,然后再计算表达式2的值,再判断表达式2的值,决定是否执行循环体,如此重复,直到表达式2的值为假,结束该循环语句okfor语句、语句、while语句、语句、do/while语句比较:语句比较:int i=1,sum=0;/循环初始条件循环初始条件while(i=4)sum+=i;i+;/修改循环条件修改循环条件 int i=1,sum=0;/循环初始条件循环初始条件do sum+=i;i+;/修改循环条件修改循环条件 while(i=4);int i,sum=0;for(i=1;i=4;i+)sum+=i;/*习惯上:表达式习惯上:表达式1 1:循环初始条件;表达式:循环初始条件;表达式2 2:循环:循环终止条件;表达式终止条件;表达式3 3:修改循环条件:修改循环条件*/okokfor 语句的应用语句的应用forfor语句的几点说明:语句的几点说明:(1)for语句属于先判断型,与语句属于先判断型,与while语句完全等同。
语句完全等同2)for语句中的三个表达式都是包含逗号表达式在内的语句中的三个表达式都是包含逗号表达式在内的任意表达式任意表达式如【例如【例2.11】中的循环部分用】中的循环部分用for语句可描述为:语句可描述为:for(i=1,sum=0;i=100;i+)sum+=i;(3)for语句中的三个表达式可部分或全部省略,但两个语句中的三个表达式可部分或全部省略,但两个分号不能省略如上述语句还可写为:分号不能省略如上述语句还可写为:i=1;sum=0;for(;i=100;)sum+=i;i+;实际上,表达式实际上,表达式2也可省略,形如也可省略,形如for(;)这种情况下,约定表达式这种情况下,约定表达式2的值为的值为1,即等同,即等同for(;1;)死循环,用死循环,用break跳出okfor 语句的应用语句的应用【例【例2.142.14】运行结果:运行结果:0 1 1 2 35 8 13 21 3455 89 144 233 377610 987 1597 2584 4181那么怎样才能从兔子问题推导出那么怎样才能从兔子问题推导出Fibonacci数列呢?数列呢?设本月底兔子数为设本月底兔子数为a,上月底兔子数,上月底兔子数b,两月前月底兔子数为,两月前月底兔子数为c。
那么两月前的所有兔子,包括老兔子和当月新生的兔子本月那么两月前的所有兔子,包括老兔子和当月新生的兔子本月都可以生小兔子,即本月新生兔子总数是两月前的兔子数都可以生小兔子,即本月新生兔子总数是两月前的兔子数c,所以本月兔子总数所以本月兔子总数a等于上月兔子数等于上月兔子数b与两月前兔子数与两月前兔子数c(即本即本月新生兔子数月新生兔子数)之和,即:之和,即:a=b+c;这就是这就是Fibonacci数列例例2.142.14】设计程序输出设计程序输出FibonacciFibonacci数列的前数列的前2020项项okfor 语句的应用语句的应用也可以另设计一个算法:安排四个变量:兔子总数也可以另设计一个算法:安排四个变量:兔子总数s,成年,成年兔数量兔数量a,一月兔数量,一月兔数量b,初生兔数量,初生兔数量c;a=a+b;/本月成年兔为上月一月兔与成年兔之和本月成年兔为上月一月兔与成年兔之和b=c;/本月一月兔数量为上月初生兔本月一月兔数量为上月初生兔c=a;/本月底初生兔数量为本月成年兔数量本月底初生兔数量为本月成年兔数量s=a+b+c;/本月底兔总数本月底兔总数代入初值:代入初值:a=0;b=0;c=1;就可以进行递推。
就可以进行递推例【例2.152.15】输入一个不超过输入一个不超过9 9位的整数,将其反向位的整数,将其反向后输出ok2.3.4 循环的嵌套循环的嵌套【例【例2.16】打印九九表打印九九表嵌套循环:嵌套循环:当循环语句中的循环体中又有循环语句时,就构成了嵌套当循环语句中的循环体中又有循环语句时,就构成了嵌套循环嵌套层次一般不超过嵌套层次一般不超过3层,以保证可读性层,以保证可读性例【例2.172.17】打印如下图形打印如下图形ok2.4 转向语句转向语句break语句语句 return语句语句 goto 语句语句 continue语句语句 ok2.4 转向语句转向语句 break语句只能用在语句只能用在switch语句语句和和循环语句循环语句中,中,用来跳出用来跳出switch语句或提前终止循环,转去执行语句或提前终止循环,转去执行switch语句或循环语句之后的语句语句或循环语句之后的语句在在for循环中可以用循环中可以用break结束循环:结束循环:for(;)if()break;在多重循环中,在多重循环中,break语句只能终止其所在层次的循环语句只能终止其所在层次的循环BreakBreak语句:语句:【例【例2.18】给定正整数给定正整数m,判定其是否为素数。
判定其是否为素数ok2.4 转向语句转向语句 continue continue语句只能用在语句只能用在循环语句循环语句中,用中,用来来终止本次循环终止本次循环当程序执行到当程序执行到continuecontinue语语句时,将跳过其后尚未执行的循环体语句,句时,将跳过其后尚未执行的循环体语句,开始下一次循环开始下一次循环下一次循环是否执行仍然下一次循环是否执行仍然取决于循环条件的判断取决于循环条件的判断continuecontinue语句与语句与breakbreak语句的区别在于,语句的区别在于,continuecontinue语句结束的只是语句结束的只是本次循环本次循环,而,而breakbreak结束的是结束的是整个循环整个循环continuecontinue语句:语句:ok例:例:输出输出1100内内3的倍数分析:设置整型变量分析:设置整型变量I从从1变化到变化到100,依次测试,依次测试I是否是否3的倍数,算法属于穷举法的倍数,算法属于穷举法for(I=1;I=100;I+)if(I%3!=0)continue;/I不是不是3的倍数,不输出,继续下一个的倍数,不输出,继续下一个I;输出输出I的值;的值;/I是是3的倍数才输出的倍数才输出 ok2.4 转向语句转向语句 goto goto语句和标号语句一起使用,所谓标号语句语句和标号语句一起使用,所谓标号语句是用标识符标识的语句,它控制程序从是用标识符标识的语句,它控制程序从gotogoto语句所语句所在的地方转移到标号语句处。
在的地方转移到标号语句处gotogoto语句会导致程序语句会导致程序结构混乱,可读性降低,而且它所完成的功能完全结构混乱,可读性降低,而且它所完成的功能完全可以用算法的三种基本结构实现,因此一般不提倡可以用算法的三种基本结构实现,因此一般不提倡使用使用gotogoto语句但在某些特定场合下语句但在某些特定场合下gotogoto语句可能语句可能会显出价值,比如在多层循环嵌套中,要从深层地会显出价值,比如在多层循环嵌套中,要从深层地方跳出所有循环,如果用方跳出所有循环,如果用breakbreak语句,不仅要使用多语句,不仅要使用多次,而且可读性较差,这时次,而且可读性较差,这时gotogoto语句可以发挥作用语句可以发挥作用gotogoto语句:语句:ok2.4 转向语句转向语句return语句用于结束函数的执行,返回调用者,语句用于结束函数的执行,返回调用者,如果是主函数,则返回至操作系统如果是主函数,则返回至操作系统利用一个利用一个return语句可以将一个数据返回给调语句可以将一个数据返回给调用者通常,当函数的返回类型为用者通常,当函数的返回类型为void时,时,return语句可以省略,如果使用也仅作为函数语句可以省略,如果使用也仅作为函数或程序结束的标志。
或程序结束的标志return语句:语句:ok2.5 结构化程序设计思想(选读)结构化程序设计思想(选读)传统的程序设计方法可以归结为,将程序定义为处理数据的一系列过程这种设计方法的着眼点是,特点是数据与程序分离,即数据与数据处理分离结构化程序设计的基本思想是采用的设计方法和的控制结构结构化程序设计方法:结构化程序设计方法:ok2.5 结构化程序设计思想(选读)结构化程序设计思想(选读)举一个简单的例子,要求读入一组整数,统计其中举一个简单的例子,要求读入一组整数,统计其中正整数和负整数的个数正整数和负整数的个数该任务的模块结构及细化过程如下:该任务的模块结构及细化过程如下:1.1.读入数据读入数据2.2.统计正数、负数统计正数、负数的个数的个数;3.输出结果输出结果 2.1 2.1 如数大于如数大于0 0,正整数个数加,正整数个数加1 12.2 2.2 如数小于如数小于0 0,负整数个数加,负整数个数加1 12.3:2.3:取下一个整数取下一个整数正整数个数为正整数个数为0 0;负整数个数;负整数个数0 0 取第一个整数取第一个整数重复重复至统至统计完计完ok2.5 结构化程序设计思想(选读)结构化程序设计思想(选读)(1 1)难以适应大型软件的设计。
难以适应大型软件的设计由于数据与数据处理相由于数据与数据处理相对独立,在大型多文件软件系统中,随着数据量的增大,对独立,在大型多文件软件系统中,随着数据量的增大,程序越来越变得难以理解,多个文件之间的数据沟通也程序越来越变得难以理解,多个文件之间的数据沟通也变得困难,还容易产生意想不到的结果,即所谓副作用变得困难,还容易产生意想不到的结果,即所谓副作用2 2)程序可重用性差程序可重用性差处理方法的改变或数据类型的改处理方法的改变或数据类型的改变都将导致重新设计,这种额外开销与可重用性相左,变都将导致重新设计,这种额外开销与可重用性相左,称为重复投入称为重复投入 结构化程序设计结构化程序设计缺陷:缺陷:ok2.6 常用算法的应用实例常用算法的应用实例【例【例2.202.20】中国中国古代数学史上著名的古代数学史上著名的“百鸡问题百鸡问题”【例【例2.212.21】用欧基里德算法(也称辗转法)用欧基里德算法(也称辗转法)求两个整数的最大公约数求两个整数的最大公约数【例【例2.232.23】输入一个输入一个8 8位二进制数,将其转位二进制数,将其转换为十进制数输出换为十进制数输出例【例2.192.19】用筛选法求用筛选法求100100之内的所有素数之内的所有素数【例【例2.222.22】输入一个小于输入一个小于1 1的数的数x x,求,求sinxsinx的的近似值近似值ok2.7 枚举类型枚举类型 2.7.1 2.7.1 枚举类型的定义枚举类型的定义 2.7.2 2.7.2 枚举变量的使用枚举变量的使用 枚举类型枚举类型(enumerate)(enumerate)是是c+c+中的一种派生数据类中的一种派生数据类型,它是用户定义的若干枚举常量的集合。
型,它是用户定义的若干枚举常量的集合枚举类型的变量,只能取枚举常量表中所列的值枚举类型的变量,只能取枚举常量表中所列的值定义枚举类型的主要定义枚举类型的主要目的是增加程序的可读性目的是增加程序的可读性ok2.7.1 枚举类型的定义枚举类型的定义 枚举类型定义:枚举类型定义:enum ;关键字关键字enum指明其后的标识符是一个类型的名字,枚举常量指明其后的标识符是一个类型的名字,枚举常量表中列出该类型的所有取值,各枚举常量之间以表中列出该类型的所有取值,各枚举常量之间以“,”间隔例:例:enum color_set1 RED,BLUE,WHITE,BLACK;enum week Sun,Mon,Tue,Wed,Thu,Fri,Sat;枚举常量(或称枚举成员)是以标识符形式表示的整型量,枚举常量(或称枚举成员)是以标识符形式表示的整型量,非法定义实例:非法定义实例:enum letter_set a,d,F,s,T;/枚举常量只能是标识符枚举常量只能是标识符enum year_set2000,2001,2002,2003,2004,2005;/改为改为y2000等则正确等则正确ok2.7.1 枚举类型的定义枚举类型的定义 枚举常量:枚举常量:枚举常量代表该枚举类型的变量可能取的值,编译系枚举常量代表该枚举类型的变量可能取的值,编译系统为每个枚举常量指定一个整数值,缺省状态下,这个整统为每个枚举常量指定一个整数值,缺省状态下,这个整数就是所列举元素的序号,序号从数就是所列举元素的序号,序号从0开始。
如上例中开始如上例中RED、BLUE、WHITE、BLACK的值分别为的值分别为0、1、2、3用户也可以在类型定义时为部分或全部枚举常量指定整用户也可以在类型定义时为部分或全部枚举常量指定整数值,在第一个指定值之前的枚举常量仍按缺省方式取值,数值,在第一个指定值之前的枚举常量仍按缺省方式取值,而指定值之后的枚举常量按依次加而指定值之后的枚举常量按依次加1的原则取值各枚举常的原则取值各枚举常量的值可以重复,但各枚举常量标识符必须不同量的值可以重复,但各枚举常量标识符必须不同例:例:enum fruit_set apple,orange,banana=1,peach,grapeenum week Sun=7,Mon=1,Tue,Wed,Thu,Fri,Sat;枚举常量枚举常量apple、orange、banana、peach、grape的值的值分别为分别为0、1、1、2、3枚举常量枚举常量Sun,Mon,Tue,Wed,Thu,Fri,Sat的值分别为的值分别为7、1、2、3、4、5、6ok2.7.1 枚举类型的定义枚举类型的定义 枚举型变量定义:枚举型变量定义:定义枚举类型之后,就可以定义枚举类型的变量;定义枚举类型之后,就可以定义枚举类型的变量;亦可类型与变量同时定义(甚至类型名可省):亦可类型与变量同时定义(甚至类型名可省):color_set1 color1,color2;enum Sun,Mon,Tue,Wed,Thu,Fri,Sat weekday1,weekday2;枚举变量的取值范围就是整型数的一个子集。
枚举枚举变量的取值范围就是整型数的一个子集枚举变量占用内存的大小与整型数相同变量占用内存的大小与整型数相同ok2.7.2 枚举类型的变量的使用枚举类型的变量的使用 枚举类型应用要点:枚举类型应用要点:1、赋值包括将枚举常量值赋给枚举变量和两个同类型变量之赋值包括将枚举常量值赋给枚举变量和两个同类型变量之间赋值不能直接将整型量赋给枚举变量,两个不同类型的枚间赋值不能直接将整型量赋给枚举变量,两个不同类型的枚举变量之间也不能相互赋值例如:举变量之间也不能相互赋值例如:enum color_set2 GREEN,RED,YELLOW,WHITE;color_set2 color3,color4;color3=RED;/合法合法color4=color3;/合法,合法,color4的值为的值为REDcolor1=1;/非法,不能直接将整性常量赋给枚举变量非法,不能直接将整性常量赋给枚举变量color2=color3;/非法,非法,color2类型是类型是color_set1,/color3类型是类型是color_set2,不能相互赋值,不能相互赋值ok2.7.2 枚举类型的变量的使用枚举类型的变量的使用 枚举类型应用要点:枚举类型应用要点:2 2、由于枚举常量本身是一个整数值,因此也允许将一个枚举、由于枚举常量本身是一个整数值,因此也允许将一个枚举量赋给整型变量。
但量赋给整型变量但不允许将一个整型变量赋给枚举量不允许将一个整型变量赋给枚举量,即即使整型变量取值合适,也必须将整型变量强制转换为枚举型使整型变量取值合适,也必须将整型变量强制转换为枚举型例如:例如:int i,j;i=color3;/合法,合法,i的值为的值为1j=GREEN;/合法,合法,j的值为的值为0color3=i;/非法非法3、关系运算可以是同一枚举类型的两个枚举变量之间或一个、关系运算可以是同一枚举类型的两个枚举变量之间或一个枚举变量和一个枚举常量之间,用它们所取的值(序号)比较枚举变量和一个枚举常量之间,用它们所取的值(序号)比较例如:例如:if(color3=color4)cout”相等相等”;if(color3!=WHITE)coutcolor1/非法非法 cout)和插入运算符()和插入运算符()进行也)进行也可以用读字符的可以用读字符的get()和读字符串的和读字符串的getling()等函数读等函数读写是在文件缓冲区中进行写是在文件缓冲区中进行4)关闭文件当打开一个文件进行读写后,应该显式地关关闭文件当打开一个文件进行读写后,应该显式地关闭该文件与打开文件相对应:闭该文件。
与打开文件相对应:ifile.close();ofile.close();关闭文件时,系统把与该文件相关联的文件缓冲区关闭文件时,系统把与该文件相关联的文件缓冲区中的数据写到磁盘文件中,保证文件的完整;同时把磁盘中的数据写到磁盘文件中,保证文件的完整;同时把磁盘文件名与文件流对象之间的关联断开,可防止误操作修改文件名与文件流对象之间的关联断开,可防止误操作修改了磁盘文件了磁盘文件例【例2.25】将百鸡问题计算结果存入文件将百鸡问题计算结果存入文件例【例2.26】读出存放百鸡问题计算结果的文件读出存放百鸡问题计算结果的文件ok第二章第二章 基本控制结构程序设计基本控制结构程序设计结束欢迎再来!ok if 语句【例语句【例2 24 4】【例【例24】输入一个年份,判断是否闰年输入一个年份,判断是否闰年算法分析算法分析:假定年份为假定年份为year,闰年的条件是闰年的条件是:year%4=0&year%100!=0|year%400=0int main()int year;cout输入年份输入年份:year;if (year%4=0&year%100!=0|year%400=0)coutyear年是闰年年是闰年endl;else cout year年不是闰年年不是闰年endl;return 0;okok分析:读入三个数,先求出两个数中分析:读入三个数,先求出两个数中较大者,再将该大数与第三个数比较,较大者,再将该大数与第三个数比较,求出最大数。
求出最大数int main()int a,b,c,max;coutabc;couta=atb=b tc=c=b)max=a;else max=b;if(cmax)max=c;cout“最大数为最大数为:”maxendl;return 0;if 语句【例语句【例2 25 5】【例【例2.5】从键盘上输入三个整数,输出其中的最大数从键盘上输入三个整数,输出其中的最大数okok/方法方法1:采用:采用if中嵌套形式中嵌套形式int main()int a,b,c,max;coutabc;couta=atb=b tc=cb)if(ac)max=a;/ab且且ac else max=c;/ab且且ac)max=b;/acelse max=c;/a=b且且bccout最大数最大数max=max;return 0;if 语句【例语句【例2 26 6】【例【例2.6】用嵌套】用嵌套if语句完成【例语句完成【例2.5】的任务okok/方法方法2:采用:采用else中嵌套形式中嵌套形式int main()int a,b,c,max;coutabc;couta=atb=b tc=cb&ac)max=a;else if(ba&bc)max=b;else max=c;cout最大数为最大数为:max=max;return 0;if 语句【例语句【例2 26 6】okok【例【例2.72.7】某商场优惠活动规定,某种商品单某商场优惠活动规定,某种商品单价为价为8080元,一次购买元,一次购买5 5件以上件以上(包含5件)1010件以下件以下(不包含10件)打打9 9折,一次购买折,一次购买1010件以上件以上(包含10件)打打8 8折。
设计程序根据客户的购买量计折设计程序根据客户的购买量计 算总价算法算法1、输入购买件数、输入购买件数count,设置单价,设置单价price=80(元元)2、根据、根据count值确定折扣率值确定折扣率discount;3、实际售价、实际售价amount=price*count*discount;4、输出、输出amount的值算法细化:算法细化:2.1、if(count=5&count=10)discount=0.8;if if 语句【例语句【例2 27 7】okint main()float price,discount,amount;/单价单价,折扣折扣,总价总价 int count;/购买件数购买件数 cout输入输入单价单价:price;cout输入购买件数输入购买件数:count;if(count5)discount=1;else if(count10)discount=0.9;else discount=0.8;amount=price*count*discount;cout 单价:单价:price endl;cout 购买件数:购买件数:count t折扣:折扣:“discountendl;cout总价:总价:amount0,方程有两个不同实根;方程有两个不同实根;*若若delta0,方程无实根。
方程无实根if if 语句【例语句【例2 28 8】ok#include#include using namespace std;int main()float a,b,c;float delta,x1,x2;cout输入三个系数输入三个系数a(a!=0),b,c:abc;couta=atb=btc=cendl;delta=b*b-4*a*c;求一元二次方程的根源程序求一元二次方程的根源程序 if if 语句语句【例【例2 28 8】okif(delta=0)cout方程有两个相同实根方程有两个相同实根:;coutx1=x2=-b/(2*a)0)delta=sqrt(delta);x1=(-b+delta)/(2*a);x2=(-b-delta)/(2*a);cout方程有两个不同实根方程有两个不同实根:;coutx1=x1tx2=“x2endl;else cout方程无实根方程无实根!endl;/delta0return 0;请在请在VC+VC+平台上运行,输入不同的系数,使程序所有分支都平台上运行,输入不同的系数,使程序所有分支都可以被执行一次可以被执行一次if if 语句语句【例【例2 28 8】ok不带不带breakbreak的开关语句实例的开关语句实例【例【例2.9】运输公司对所运货物实行运输公司对所运货物实行分段计费分段计费。
设运设运输里程为输里程为s,则运费打折情况如下:,则运费打折情况如下:s250 不打折扣不打折扣250=s500 2%折扣折扣500=s1000 5%折扣折扣1000=s20008%折扣折扣2000=s300010%折扣折扣3000=s 15%折扣折扣2000=s3000 10%折扣折扣1000=s2000 8%折扣折扣500=s1000 5%折扣折扣250=s500 2%折扣折扣s250 不打折扣不打折扣不带不带breakbreak的开关语句实例的开关语句实例okint main()int c,s,s1;double p,w,d,f;cout输入运输单价输入运输单价p,重量,重量w和里程和里程s:pws;f=0;s1=s;c=s/250;switch(c)default:d=0.15;f+=p*w*(s-3000)*(1-d);s=3000;case 8:case 9:case 10:case 11:d=0.1;f+=p*w*(s-2000)*(1-d);s=2000;case 4:case 5:case 6:case 7:d=0.08;f+=p*w*(s-1000)*(1-d);s=1000;case 2:case 3:d=0.05;f+=p*w*(s-500)*(1-d);s=500;case 1:d=0.02;f+=p*w*(s-250)*(1-d);s=250;case 0:d=0;f+=p*w*s*(1-d);cout运输单价运输单价:pt重量重量:wt里程里程:s1endl;cout折扣后运费折扣后运费:fendl;return 0;请在请在VC+平台上运行,输入不同的里程。
平台上运行,输入不同的里程ok【例【例2.10】设计一个计算器程序,实现加、减、乘、除运算设计一个计算器程序,实现加、减、乘、除运算分析:分析:读入两个操作数和运算符,根据运算符完成相应运算读入两个操作数和运算符,根据运算符完成相应运算include using namespace std;int main()float num1,num2;char op;cout输入操作数输入操作数1,运算符,操作数,运算符,操作数2:num1opnum2;switch(op)case+:coutnum1opnum2=num1+num2endl;break;case-:coutnum1opnum2=num1-num2endl;break;case*:coutnum1opnum2=num1*num2endl;break;case/:coutnum1opnum2=num1/num2endl;break;default:coutop是无效运算符是无效运算符!;return 0;常量表达式采用字符型,上机运行一下常量表达式采用字符型,上机运行一下ok while 语句语句【例【例2.11】【例【例2.11】求求1+2+3+4+100的值。
的值okN N个连续整数相加算法个连续整数相加算法1 1、设置变量、设置变量i i用来放加数,变量用来放加数,变量sumsum用来放被加数与用来放被加数与和值和值,并初始化并初始化;2 2、从第一个数开始,依次将加数赋给、从第一个数开始,依次将加数赋给i i,并进行操,并进行操作作sumsumsum+isum+i,称为累加;,称为累加;3 3、输出、输出sumsum;细化算法细化算法2 2:whilewhile(还有加数还有加数)i=i=当前加数;当前加数;sum+=i;sum+=i;i i准备接受下一个加数;准备接受下一个加数;ok源程序如下:源程序如下:#include using namespace std;const int n=100;/用常变量利于修改程序用常变量利于修改程序int main()int i=1,sum=0;/循环初始条件循环初始条件 while(i=n)sum+=i;i+;/修改循环条件修改循环条件 coutsum=sumendl;return 0;在在VC+VC+平台上运行,试一试是否正确平台上运行,试一试是否正确okok【例【例2.12】用迭代法求用迭代法求a的平方根近似值。
的平方根近似值求平方根的迭代公式为:求平方根的迭代公式为:要求前后两个迭代根之差小于要求前后两个迭代根之差小于10-5do-while 语句语句【例【例2.12】迭代法求解:迭代法求解:a是已知正数,是已知正数,x 0是迭代初值,给是迭代初值,给x 0一个一个值,假定值,假定 x 0=a/2;则用迭代公式依次计算:;则用迭代公式依次计算:x1=(x0+a/x0)/2;x2=(x1+a/x1)/2;xk+1=(xk+a/xk)/2;当当|xk+1 xk|0)及较小正数及较小正数delta(也可用常变量也可用常变量);2、x 0=a/2;用迭代公式算用迭代公式算 x1=(x0+a/x0)/2;3、while(|x1 x0|=delta)x 0=x 1 ;/把最近的值给把最近的值给x 0 x1=(x0+a/x0)/2;/求求xk+1时只需要知道时只需要知道xk的值,所以只需的值,所以只需2个变量个变量4、取、取x1的值为的值为a的平方根近似值,输出的平方根近似值,输出2、3步骤很适合用步骤很适合用do/while语句实现:语句实现:x 1=a/2;dox0=x1;x1=(x0+a/x0)/2;while(|x1 x0|=delta);和迭代法对应的程序算法是和迭代法对应的程序算法是递推算法:递推算法:okint main()float x0,x1,a;couta;if(a0)couta不能开平方不能开平方!=1e-5);cout a的平方根为:的平方根为:x1endl;return 0;在在VC+VC+平台上运行,输入平台上运行,输入2 2,3 3,4 4,5 5试一试是否正确试一试是否正确ok【例【例2.13】输入一段文本,统计文本的行数、单输入一段文本,统计文本的行数、单词数及字符数。
假定单词之间以空格或跳格或换词数及字符数假定单词之间以空格或跳格或换行符间隔,且文本开始没有空行行符间隔,且文本开始没有空行算法分析算法分析:1、逐个读入文本中的字符,直到读到一个输入结、逐个读入文本中的字符,直到读到一个输入结束符束符EOF为止2、如何算行数?行结束标志为读到字符、如何算行数?行结束标志为读到字符n;3、如何算单词数?设一个变量、如何算单词数?设一个变量isword,读到字符,读到字符 时时isword=1,读到间隔符时,读到间隔符时isword=0;如果读到;如果读到一个字符而此时一个字符而此时isword值为值为0,则说明刚开始读一,则说明刚开始读一个单词;(如果读到一个间隔符而此时个单词;(如果读到一个间隔符而此时isword值值为为1,则说明刚读完一个单词;),则说明刚读完一个单词;)4、如何算字符数?剔除间隔符即所求的数量如何算字符数?剔除间隔符即所求的数量do-while 语句语句【例【例2.13】okokdo-while 语句语句【例【例2.13】算法:算法:1、设置变量、设置变量nline、nword、nch分别代表行数、分别代表行数、单词数、非分隔字符数,并初始化单词数、非分隔字符数,并初始化;设置变量设置变量isword来辅助统计单词数来辅助统计单词数;2、do从键盘读入一个字符从键盘读入一个字符c;if(c=n)nline+;if(是单词开头是单词开头)nword+;if(c不是分隔符不是分隔符)nch+;while(c!=EOF);3、输出统计结果。
输出统计结果okint main()int c;int nline=0,nword=0,nch=0,isword=0;cout输入一段文本(无空行):输入一段文本(无空行):endl;do c=cin.get();if(c=n)nline+;/遇换行符行数遇换行符行数+1 if(c!=&c!=t&c!=n)/读到非间隔符读到非间隔符 if(isword=0)nword+;/在单词的起始处给单词数在单词的起始处给单词数+1 nch+;/字符数加字符数加+1 isword=1;else isword=0;/读到间隔符读到间隔符 while(c!=EOF);cout”行数:行数:”nlineendl;cout”单词数:单词数:”nwordendl;cout”字符数:字符数:”ncharendl;return 0;ok【例【例2.14】设计程序输出设计程序输出Fibonacii数列的前数列的前20项,项,要求每行输出要求每行输出5个数据Fibonacii数列定义如下:数列定义如下:1n 1)-fib(n2)-fib(n1n 1 0n 0 fib(n)算法分析:算法分析:除了第除了第0项和第项和第1项外,每一项都是项外,每一项都是由类似方法产生,即前两项之和;所以求当前由类似方法产生,即前两项之和;所以求当前项时,只需要记住前两项;程序不需要为每一项时,只需要记住前两项;程序不需要为每一项设置专用变量;项设置专用变量;属属递推算法递推算法。
for 语句的应用语句的应用【例【例2.142.14】ok算法:算法:1、设置变量、设置变量n表示第几项,变量表示第几项,变量 f 1和和 f 2用来记住用来记住当前项当前项f 3之前的两项之前的两项;变量初始化;变量初始化n=0;2、第、第0项项 f 1=0;第第1项项 f 2=1;输出第输出第0项和第项和第1项;项;while(当前项不到第(当前项不到第20项)项)当前项等于前两项之和:当前项等于前两项之和:f 3=f 1+f 2;按要求输出按要求输出当前项当前项 f 3;修改最前两项:修改最前两项:f 1=f 2;f 2=f 3;for 语句的应用语句的应用【例【例2.142.14】ok程序如下:程序如下:/文件名:文件名:Ex2_14.cppint main()int fib0=0,fib1=1,fib2,n;coutsetw(5)fib0setw(5)fib1 endl;for(n=3;n=20;n+)fib2=fib0+fib1;coutsetw(5)fib2;if(n%5=0)coutendl;/控制每行控制每行5个数据个数据fib0=fib1;fib1=fib2;return 0;for 语句的应用语句的应用【例【例2.142.14】ok【例【例2.15】输入一个不超过输入一个不超过9 9位的整数,将其反向位的整数,将其反向后输出。
例如输入后输出例如输入247247,变成,变成742742输出算法分析:算法分析:1、将整数的各个数位逐个分开,用一个数组保存、将整数的各个数位逐个分开,用一个数组保存各位的值,然后反向组成新的整数各位的值,然后反向组成新的整数2、将整数各位数字分开的方法是,通过求余得到、将整数各位数字分开的方法是,通过求余得到个位数,然后将整数缩小十倍,再求余,并个位数,然后将整数缩小十倍,再求余,并重复重复上述过程上述过程,分别得到十位、百位,分别得到十位、百位,直到直到整数整数的值变成的值变成0为止为止for 语句的应用语句的应用【例例2.15】okok数据处理:数据处理:1、设置变量、设置变量num表示输入的整数,整型数组表示输入的整数,整型数组digit9用来存用来存放放num 的各个位;变量的各个位;变量i用来表示数组的当前下标;用来表示数组的当前下标;算法:算法:1、输入、输入num;变量初始化:变量初始化:i=0;2、while(num!=0)num对对10取余取余,得得num的当前个位数放入的当前个位数放入digiti;num整除整除10,即去掉个位数,十位变个位,即去掉个位数,十位变个位,百位变十位,百位变十位,;i+;/数组数组digit准备记录下一位;准备记录下一位;3、将数组元素按下标从低到高的顺序反向组合;、将数组元素按下标从低到高的顺序反向组合;ok程序如下:程序如下:int main()int i,num,subscript;int digit9;cout“输入一个不超过输入一个不超过9位的整数:位的整数:num;cout“原来的整数为:原来的整数为:num0);for(i=0;i。