第五章成员函数精选文档.ppt
第五章成员函数本讲稿第一页,共八十四页5.1 成员函数的概念 为了实现对象的行为,我们把一些相关的语句组织在一起,并给它们注明相应的名称,形成一组织在一起,并给它们注明相应的名称,形成一些相对独立而且便于管理和阅读的小块程序,每个小程序块描述了一个完整的行为,这种形式的组合就构成了成员函数。组合就构成了成员函数。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第二页,共八十四页5.2 算法描述 5.2.1 算法的概念 一个完整的对象应该包括两个方面的内容,即对数据的描述(对象属性)和对操作的描述(对象行为)。对操作的描述也就是算法,是设计和实现对象行为的灵魂。一个完整的算法应该具有以下5个特性:有穷性、确定性、有效性、输入性和输出性。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三页,共八十四页5.2.2 算法的表示 为了表示一个算法,可以采用多种形式。最常见的几种方法有自然语言表示法、流程图表示法、伪代码表示法和计算机语言表示法。自然语言表示法:自然语言表示法就是用我们日常生活中的语言来表示算法的实现过程,对采用何种语言没有限制。但是采用自然语言表示往往不太严格,容易造成歧义。另外,用这种方法描述包含分支和循环的算法不太方便。因此,自然语言表示法很少用来描述复杂的算法。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四页,共八十四页面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版图图5.1 5.1 一般流程图表示算法一般流程图表示算法 流程图表示法:流程图表示法:流程图就是用一些图框表示流程图就是用一些图框表示各种操作。用流程图来表示算法各种操作。用流程图来表示算法最大的优点就是直观形象,便于最大的优点就是直观形象,便于理解,并且实用性强,能够方便理解,并且实用性强,能够方便的表示包的表示包含分支和循环的结构,避免了用自然语言表示算法的不足。本讲稿第五页,共八十四页面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版图图5.2 N-S5.2 N-S流程图表示算法流程图表示算法本讲稿第六页,共八十四页伪代码表示法:伪代码是用介于自然语言和计算机语言之间的文字和符号伪代码是用介于自然语言和计算机语言之间的文字和符号来描述算法。从结构上看,伪代码表示法类似于最终的计算机来描述算法。从结构上看,伪代码表示法类似于最终的计算机语言,每一行就表示一个基本的操作。它不用图形符号,因此语言,每一行就表示一个基本的操作。它不用图形符号,因此书写方便、格式紧凑,也易于理解,便于向最终的程序过渡。书写方便、格式紧凑,也易于理解,便于向最终的程序过渡。伪代码表示法书写格式比较自由,容易直观表达出设计者的伪代码表示法书写格式比较自由,容易直观表达出设计者的思想。同时,书写的算法也容易修改,很容易写出结构化的思想。同时,书写的算法也容易修改,很容易写出结构化的算法。算法。因此,这种方法一般被专业的软件开发人员采用,特别是在详细设计中采用伪代码表示法,可以使以后的编码阶段变得简单。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第七页,共八十四页计算机语言表示法:一个算法要拿到计算机上去运行,最终还是得采用一个算法要拿到计算机上去运行,最终还是得采用计算机语言表示。计算机是无法识别流程图和伪代码的。计算机语言表示。计算机是无法识别流程图和伪代码的。只有严格按照计算机语言语法编写的程序才能被计算机只有严格按照计算机语言语法编写的程序才能被计算机执行。目前使用的计算机语言多种多样,本书所介绍的执行。目前使用的计算机语言多种多样,本书所介绍的面向对象的程序设计语言(面向对象的程序设计语言(C+C+)就是种很好的描述和)就是种很好的描述和实现算法的工具。实现算法的工具。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第八页,共八十四页5.3 成员函数的定义与调用 5.3.1 成员函数的定义面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版定义一个成员函数必须具备四个条件:定义一个成员函数必须具备四个条件:函数必须具有返回值类型,即函数必须有返回值,且该返回值的类型应该与函数返回值的类型一致 函数必须具有一个名字,即函数名。函数必须具有一个形参(形式参数)列表,C+规定,形参列表以左括号“(”开始,到右括号“)”结束,且各个形参之间用“,”分开。函数要完成一定的功能,必须具有一个函数体,其中,前面函数要完成一定的功能,必须具有一个函数体,其中,前面的三个条件构成了函数的原型。的三个条件构成了函数的原型。本讲稿第九页,共八十四页说明一个函数原型的一般形式有两种:函数返回值类型 函数名(参数类型1 参数名1,参数类型2 参数名2,);函数返回值类型函数返回值类型 函数名函数名(参数类型参数类型1,1,参数类型参数类型2,);2,);以上两种方法均可以使用,但是为了增加程序的可读性建议使用第一种方法。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第十页,共八十四页成员函数的定义:成员函数的定义:(1 1)对于代码较少的成员函数的定义,可以直接在类中进行。)对于代码较少的成员函数的定义,可以直接在类中进行。)对于代码较少的成员函数的定义,可以直接在类中进行。)对于代码较少的成员函数的定义,可以直接在类中进行。class Circleclass Circle protected protected:int Radiusint Radius;publicpublic:fioat circle_area(fioat pi)return pi*Radius*Radius;fioat circle_area(fioat pi)return pi*Radius*Radius;(2 2)对于代码较多的成员函数的定义,通常只在类中进行原型说明,在类外对成员函数进行定)对于代码较多的成员函数的定义,通常只在类中进行原型说明,在类外对成员函数进行定)对于代码较多的成员函数的定义,通常只在类中进行原型说明,在类外对成员函数进行定)对于代码较多的成员函数的定义,通常只在类中进行原型说明,在类外对成员函数进行定义。义。义。义。class Circleclass Circle protected protected:int Radiusint Radius;publicpublic:fioat circle_area(fioat pi)fioat circle_area(fioat pi);;float Circle float Circle:circle_area(float pi)circle_area(float pi)return pi*Radius*Radius;return pi*Radius*Radius;请注意,这时的函数名应该包含:请注意,这时的函数名应该包含:类名类名(Circle)+(Circle)+作用域分辨符作用域分辨符(:)+)+原函数原函数(circle_area)(circle_area)本讲稿第十一页,共八十四页5.3.2 成员函数的调用一般形式有两种:对象名对象名.函数名函数名(实参实参1,1,实参实参2,);2,);对象指针对象指针函数名函数名(实参实参1,1,实参实参2,);2,);例如:void main()void main()cout “The area of circle=”cout “The area of circle=”Z)将!右边的结果(逻辑值)取非R按位取反运算符 A将A值按位取反R取地址与取值运算符&pX=&Y提取变量Y的地址,然后赋给指针变量pXR*X=*pY提取指针变量pY所指的地址单元的内容,然后赋给变量X类型转换运算符(类型)X=(int)Y将Y转换为整型,然后赋给XR动态内存分配运算符NewPa=new int4;创建一个整型数组,其中含有4个元素,并将首地址给PaRdeletedelete Pa;delete Pb;数组必须用delete 进行删除普通的堆对象可用delete删除面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第二十九页,共八十四页4-*X*Y将两数相乘L/X/Y将两数相除%X%Y将两数相除取其余数5+X+Y将两数相加X Y将两数相减6移位运算符A A 2将A值向右平移2位7!=X X Y判断X是否大于Y=X=X=Y判断X是否大于等于Y8=X=Y判断X是否等于YX!=Y判断X是否不等于Y9位运算符&A&B将A和B的值按位相与L10A B将A和B的值按位相异或11|A|B将A和B的值按位相或12逻辑运算符&XZ将&两边的结果(逻辑值)相与L13|XZ将|两边的结果(逻辑值)相或14条件运算符?:Z=XY?E1:E2;如果XY为真,Z等于E1的值,否则等于E2的值R面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三十页,共八十四页15赋值运算符=X=Y将Y的值赋给XR+=X+=Y将X的值加Y后,再赋给X,等价于 X=X+Y-=X-=Y将X的值减Y后,再赋给X,等价于 X=X Y*=X*=Y将X的值乘Y后,再赋给X,等价于 X=X*Y/=X/=Y将X的值除Y后,再赋给X,等价于 X=X/Y%=X%=Y将X的值对Y取余后,再赋给X,等价于 X=X%Y&=X&=Y将X的值与Y按位相与后,再赋给X,等价于 X=X&Y=X=Y将X的值与Y按位相异或后,再赋给X,等价于 X=X Y|=X|=Y将X的值与Y按位相或后,再赋给X,等价于 X=X|Y=X=Y将X的值左移Y位后,再赋给X,等价于 X=X=X=Y将X的值右移Y位后,再赋给X,等价于 X=X Y16逗号运算符,E1,E2,E3从左到右依次求出表达式E1,E2,E3的值L面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三十一页,共八十四页5.4.2 表达式 所谓表达式是指:所谓表达式是指:用运算符将运算对象(也称操作数)用运算符将运算对象(也称操作数)连接起来的、符合语法规则的式子连接起来的、符合语法规则的式子。根据连接运算对象的连接符(运算符)的不同大体上可以将根据连接运算对象的连接符(运算符)的不同大体上可以将表达式分为以下四种:表达式分为以下四种:算术运算表达式(算术运算表达式的运算结果是数值算术运算表达式(算术运算表达式的运算结果是数值 )逻辑运算表达式(逻辑运算表达式的运算结果是逻辑值逻辑运算表达式(逻辑运算表达式的运算结果是逻辑值 )赋值运算表达式(赋值运算符的结合性是从右向左的赋值运算表达式(赋值运算符的结合性是从右向左的 )逗号运算表达式(逗号运算表达式的值是最后一个表达式逗号运算表达式(逗号运算表达式的值是最后一个表达式的值的值 )面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三十二页,共八十四页注意:注意:当一个表达式中包含多种运算符时,必须考虑运算符的优先级和当一个表达式中包含多种运算符时,必须考虑运算符的优先级和结合性。结合性。可以用()改变运算符的优先级;可以用()改变运算符的优先级;例如例如:int i=1,n=2;int i=1,n=2;n=i+n 1;n=i+n 1;/因为因为“+”“+”高于高于“”“”高于高于“=”“=”,所以先运算,所以先运算i+n i+n 等于等于3 3,/再运算再运算3131得得6 6,最后,最后n=6n=6。用用“()”“()”改变先后次序如下:改变先后次序如下:int i=1,n=2;int i=1,n=2;n=i+(n 1);n=i+(n 1);/因为因为 (n1n1)高于高于“+”“+”高于高于“=”“=”,所以先运算,所以先运算n1 n y?e1:e2;x y?e1:e2;i+;i+;赋值运算符左侧必须是一个可以引用的存储单元(如:变量),决不能是表达式。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三十四页,共八十四页5.4.3 数据类型的转换类型转换就是将一种类型的值转换为另一种类型的值。类型转换就是将一种类型的值转换为另一种类型的值。隐式类型转换隐式类型转换 其转换过程是由系统按照一定的转换规则自动完成的。其转换过程是由系统按照一定的转换规则自动完成的。(1 1)当)当charchar或或shortshort型数据与型数据与intint型数据进行运算时,将型数据进行运算时,将charchar或或shortshort型装换成型装换成intint类型;类型;(2 2)当两个运算对象数据类型不一致时,在做算术运算前,)当两个运算对象数据类型不一致时,在做算术运算前,级别低的自动转换为级别高的数据类型级别低的自动转换为级别高的数据类型(3 3)在赋值表达式)在赋值表达式E1=E2E1=E2的情况下,赋值运算符右端的情况下,赋值运算符右端E2E2的结果的结果值需转换为值需转换为E1E1类型,然后赋值。类型,然后赋值。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三十五页,共八十四页显式类型转换 显式类型转换的方法有两种。(1)强制转换法 强制转换法的格式为:(类型名)表达式;如:(int)x;在强制类型转换时,得到一个所需类型的中间变量,原来变量的类型未发生变化。(2)函数法 函数法的转换格式为:类型名(表达式);如:int(x);本讲稿第三十六页,共八十四页显示类型转换有时是必需的,如前面提到的void*指针。我们必须将malloc返回的void*指针显示转换为特定的类型 int*p=static_cast(malloc(100);(int)3.1415;/就是取整数部分(int)a%10;/取a的个位数 本讲稿第三十七页,共八十四页 在程序设计过程中,使用以下三种控制结构作为算法的基本单元。事实上,任何一个成员函数的定义都离不开这三种基本结构:5.5.1 5.5.1 顺序结构顺序结构顺序结构是指程序语句按顺序,自上而下依次执行 5.5.2 5.5.2 选择结构(又称分支结构)选择结构(又称分支结构)选择结构是指能根据选择条件,改变程序走向的一种选择结构是指能根据选择条件,改变程序走向的一种语句语句 5.5.3 5.5.3 循环结构循环结构 循环结构是指能根据循环条件,重复执行某段程序的一种循环结构是指能根据循环条件,重复执行某段程序的一种语句。是代码可重用技术的一种基本形式语句。是代码可重用技术的一种基本形式 5.5 控制结构本讲稿第三十八页,共八十四页5.5.1 顺序结构 顺序结构是指程序语句按顺序,自上而下依次执行。顺序结构是指程序语句按顺序,自上而下依次执行。如,输入三角形的三边长,求三角形面积的函数。如,输入三角形的三边长,求三角形面积的函数。float f_area(float a,float b,float c)float f_area(float a,float b,float c)float s;float s;s=1.0/2 *(a+b+c);s=1.0/2 *(a+b+c);return sqrt(s*(s return sqrt(s*(s a)*(s-b)*(s-c);a)*(s-b)*(s-c);面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第三十九页,共八十四页5.5.2 选择结构(又称分支结构)if 和 if elseifif是最简单的选择语句,一般格式为:是最简单的选择语句,一般格式为:if()我们所要执行的语句多于一条时,我们所要执行的语句多于一条时,C+C+规定,必须将规定,必须将这些语句用这些语句用“”“”和和“”“”括起来。一般格式为:括起来。一般格式为:if()2 面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十页,共八十四页if elseif else是用来解决在互相对立的两种条件下,所要分别进是用来解决在互相对立的两种条件下,所要分别进行处理的两批语句。行处理的两批语句。if(if()12nelseelse n+1n+2n+k n+k+1 面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十一页,共八十四页当分支结构(即选择结构)的分支较多时,当分支结构(即选择结构)的分支较多时,C+C+提供了嵌套式的选提供了嵌套式的选择结构:择结构:if(if()1)12nelse if(else if()2)n+1n+2n+kelseelse n+k+1n+k+2n+k+m n+k+m+1 面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十二页,共八十四页 例如,设计一个函数,当输入大于例如,设计一个函数,当输入大于0 0时,输出为时,输出为1 1;当输入小于;当输入小于0 0时,输出为时,输出为-1-1;当输入等于;当输入等于0 0时,输出为时,输出为0 0;(注意本例中判断条件有;(注意本例中判断条件有三种情况)三种情况)int f_s(int x)int f_s(int x)if if(x0 x0)else if(x0)/到此排除了到此排除了x0 x0 x0和和x=0 x=0的情况的情况 x=1;x=1;elseelse/到此排除了到此排除了x0 x0 x0的情况,只剩下的情况,只剩下x=0 x=0的情况的情况 x=0;x=0;return x;return x;注意:判断条件之间存在排除关系的这种情况,一般采用注意:判断条件之间存在排除关系的这种情况,一般采用ifelseifelseifelseifelse这种形式进行处理这种形式进行处理面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十三页,共八十四页 switchswitch语句又称开关语句。主要用于根据某个整型数据的变语句又称开关语句。主要用于根据某个整型数据的变化,达到多种分支的目的。一般格式为:化,达到多种分支的目的。一般格式为:switchswitch(整型表达式(整型表达式E E)case case 整型表达式整型表达式E1:E1:语句系列语句系列1 1;break;break;/跳过下面的所有语句直接去执行语句跳过下面的所有语句直接去执行语句k+2k+2;case case 整型表达式整型表达式E2:E2:语句系列语句系列2 2;break;break;case case 整型表达式整型表达式Ek:Ek:语句系列语句系列k k;break;break;default:default:语句系列语句系列k+1k+1;/开关语句结束开关语句结束语句语句k+2k+2;面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十四页,共八十四页注意:整型表达式整型表达式E E,E1E1,E2E2,EkEk的值,是整型数据(或者的值,是整型数据(或者字符变量、字符常量)。字符变量、字符常量)。当整型表达式当整型表达式E E的值等于整型表达式的值等于整型表达式E1E1的值时,执行语句的值时,执行语句系列系列1 1;同理当整型表达式;同理当整型表达式E E的值等于整型表达式的值等于整型表达式EkEk的值时,的值时,执行语句系列执行语句系列k k。当程序执行到当程序执行到breakbreak时,将跳过下面所有的语句,执行开时,将跳过下面所有的语句,执行开关语句后的语句,即语句关语句后的语句,即语句k+2k+2。当整型表达式当整型表达式E E的值不等于整型表达式的值不等于整型表达式E1E1,E2E2,EkEk的的值时,则执行值时,则执行defaultdefault语句下的语句系列语句下的语句系列k+1k+1。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十五页,共八十四页例如,编程实现两个浮点数的四则运算函数例如,编程实现两个浮点数的四则运算函数f_arith:f_arith:float f_arith(float d1,float d2,char op)float f_arith(float d1,float d2,char op)float temp;float temp;switch(op)switch(op)case+:case+:temp=d1+d2;temp=d1+d2;break;break;/跳过下面的所有语句直接去执行跳过下面的所有语句直接去执行switchswitch语句后面的语句后面的语句语句case-:case-:temp=d1-d2;temp=d1-d2;break;break;case*:case*:temp=d1*d2;temp=d1*d2;break;break;case/:case/:temp=d1/d2;temp=d1/d2;break;break;default:default:temp=-100;temp=-100;/开关语句结束开关语句结束return temp;return temp;/函数结束函数结束面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十六页,共八十四页5.5.3 循环结构 forfor语句语句当参加循环的语句(又称循环体),只有一条语句时,其一般格式为:当参加循环的语句(又称循环体),只有一条语句时,其一般格式为:for(E1;E2;E3)for(E1;E2;E3)1 例如:计算从例如:计算从1 1到到n n的自然数的累加和函数的自然数的累加和函数f_sumf_sum。int f_sum(int n)int f_sum(int n)int i,sum=0;int i,sum=0;for(i=1;i n+1;i+)for(i=1;i n+1;i+)sum+=i;sum+=i;return sum;return sum;面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十七页,共八十四页当参加循环的语句,多于一条语句时,需要用“”和“”将循环体括起来。其一般格式为:for(E1;E2;E3)for(E1;E2;E3)12n 面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十八页,共八十四页breakbreak语句与语句与continuecontinue语句对循环的影响语句对循环的影响breakbreak语句:语句:当某个条件满足,我们想结束循环时,采用这个语句。其一当某个条件满足,我们想结束循环时,采用这个语句。其一般形式为:般形式为:for()for()if(if(条件表达式条件表达式E)E)break;break;/离开整个循环直接跳到循环体外,执行离开整个循环直接跳到循环体外,执行n+1.n+1 面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第四十九页,共八十四页continuecontinue语句:语句:当某个条件满足,我们并不想结束循环,只想跳过某些循环语句当某个条件满足,我们并不想结束循环,只想跳过某些循环语句时,采用这个语句。其一般形式为:时,采用这个语句。其一般形式为:for()for()/循环起点循环起点 1if(if(条件表达式条件表达式E)E)continue;continue;/跳过跳过2,重返循环起点,重返循环起点2/循环终点循环终点 n+1 面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十页,共八十四页 计算计算 n,n+k n,n+k 范围内的自然数中偶数的累加和(其中范围内的自然数中偶数的累加和(其中n n和和k k均为自然均为自然数)数)int f_psum(int n,int k)int f_psum(int n,int k)int sum=0;int sum=0;while(n0)while(n0)/确保确保n n是自然数才计算是自然数才计算 if(k0)if(k0)/结束计算的条件,即跳出循环结束计算的条件,即跳出循环 break;break;if(n+k-)%2!=0)/if(n+k-)%2!=0)/奇数不累加,即跳过下面的语句重返循环起点奇数不累加,即跳过下面的语句重返循环起点 continue;continue;sum+=n+k+1;sum+=n+k+1;return sum;return sum;面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十一页,共八十四页多重循环。在某个循环语句内还包含另一个循环语句。多重循环。在某个循环语句内还包含另一个循环语句。C+C+中称为多重循环中称为多重循环(或循环嵌套)。其一般格式为:(或循环嵌套)。其一般格式为:for(E1;E2;E3)for(E1;E2;E3)/外循环语句起点外循环语句起点 1/外循环体语句系列外循环体语句系列2for(E11;E22;E33)for(E11;E22;E33)/内循环语句起点内循环语句起点 1/内循环体语句系列内循环体语句系列2n /内循环语句终点内循环语句终点n /外循环语句终点外循环语句终点面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十二页,共八十四页 while while语句一般格式为:语句一般格式为:while(while()dowhile dowhile语句一般格式为:语句一般格式为:do do while(while(););面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十三页,共八十四页注意:循环语句的形式比较多,要根据需要合理选用。循环语句的形式比较多,要根据需要合理选用。while while和和dowhiledowhile型循环语句,同样可以实现多层嵌。型循环语句,同样可以实现多层嵌。break break和和continuecontinue语句均可使用于语句均可使用于whilewhile和和dowhiledowhile语句,但语句,但是,它们仅作用于本层循环上,在任何一层上要实现是,它们仅作用于本层循环上,在任何一层上要实现breakbreak和和continuecontinue的操作,都必须在这一层中增加这两条语句。的操作,都必须在这一层中增加这两条语句。在书写时,不要忘记在书写时,不要忘记dowhiledowhile语句中最后的语句中最后的“;”“;”。建议读者养成良好编程习惯,不要在循环体内说明数据建议读者养成良好编程习惯,不要在循环体内说明数据成员或者函数的原型,如:成员或者函数的原型,如:int num;int num;或者或者char*func(int a,char*func(int a,char*s);char*s);类似的声明应在循环体外。类似的声明应在循环体外。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十四页,共八十四页5.5.4 递归函数的自我调用 前面介绍了控制结构,下面我们通过递归的学习进一步前面介绍了控制结构,下面我们通过递归的学习进一步加强对控制结构的理解。加强对控制结构的理解。所谓所谓“递归递归”是指通过重复执行相同的计算来解决问题。是指通过重复执行相同的计算来解决问题。简单的说,递归就是函数直接或间接地自己调用自己。从而简单的说,递归就是函数直接或间接地自己调用自己。从而使得程序简短。编写递归程序的关键是:使得程序简短。编写递归程序的关键是:(1)(1)构造递归表达式。构造递归表达式。将将n n阶的问题转化为比阶的问题转化为比n n阶小的问题,转化以后的阶小的问题,转化以后的问题与原来的问题的解法是相同的。问题与原来的问题的解法是相同的。(2)(2)必须寻找一个明确的递归结束条件,称为递归出口。必须寻找一个明确的递归结束条件,称为递归出口。递归是在函数中出现调用函数本身的语句,只是每次调用时函数递归是在函数中出现调用函数本身的语句,只是每次调用时函数的实参值不一样,如果代码中没有包含终止调用的控制语句,将无的实参值不一样,如果代码中没有包含终止调用的控制语句,将无限循环下去。因此,通常用限循环下去。因此,通常用if if语句中条件的判断来决定是否跳出这个语句中条件的判断来决定是否跳出这个递归过程。递归过程。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十五页,共八十四页#include#include#include#include int f(int x)int f(int x)int y;int y;if(x=0|x=1)if(x=0|x=1)return 3;return 3;y=x-f(x-2);y=x-f(x-2);return y;return y;void main()void main()cout “f(5)=”f(5)endl;cout “f(5)=”f(5)endl;cout “f(6)=”f(6)endl;cout “f(6)=”f(6)endl;cout “f(8)=”f(8)endl;cout “f(8)=”f(8)endl;运行结果为:运行结果为:f(5)=5f(5)=5f(6)=1f(6)=1f(8)=7f(8)=7面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版下面请同学们看一个例子:下面请同学们看一个例子:本讲稿第五十六页,共八十四页注意:使用递归编写程序虽然代码较少,但程序的可读性较差。使用递归编写程序虽然代码较少,但程序的可读性较差。使用递归时层次不能太深,一般不超过使用递归时层次不能太深,一般不超过3 3层。多层函数递层。多层函数递归将造成系统资源的严重浪费。归将造成系统资源的严重浪费。由于递归的缺点很明显,所以在实际开发工作中不建议由于递归的缺点很明显,所以在实际开发工作中不建议使用递归。使用递归。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十七页,共八十四页5.6函数的参数的传递机制 当一个函数定义有形参时,在进行函数调用时,必须当一个函数定义有形参时,在进行函数调用时,必须提供与形参个数相同、顺序相同、类型相同的实参;或提供与形参个数相同、顺序相同、类型相同的实参;或通过类型转换能够将实参的值映射为形参类型的值。通过类型转换能够将实参的值映射为形参类型的值。在在C C中,可以使用两种传递机制将实参的值传递中,可以使用两种传递机制将实参的值传递给形参:给形参:一种被称为一种被称为值传递值传递 (值调用)。(值调用)。另一种被称为另一种被称为引用传递引用传递(引用调用)。(引用调用)。面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十八页,共八十四页5.6.1 值调用C+C+中变量的值有两种:变量本身值和变量地址值。中变量的值有两种:变量本身值和变量地址值。1.1.传值调用的特点:传值调用的特点:调用时系统先计算实参表达式的值,然后依次赋给形参。因此,调用时系统先计算实参表达式的值,然后依次赋给形参。因此,传值调用的实现机制是系统将实参拷贝一个副本给形参。在被调用的传值调用的实现机制是系统将实参拷贝一个副本给形参。在被调用的函数中参数(即参数的副本)被改变,但未改变实参的值(即不能函数中参数(即参数的副本)被改变,但未改变实参的值(即不能“回带回带”)。)。例如:交换两个变量例如:交换两个变量a a和和 b b的值(采用传值调用)。的值(采用传值调用)。void f_swap1(int A,int B)void f_swap1(int A,int B)int temp;int temp;temp=A;temp=A;A=B;A=B;B=temp;B=temp;cout “A=”A”“”B=”Bendl;cout “A=”A”“”B=”Bendl;面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第五十九页,共八十四页void main()int a=5,b=6;f_swap1(a,b);/执行完该语句后,变量的值没有改变cout “a=”a“”“b=”bendl;运行结果如下:A=6 B=5 /函数内的结果a=5b=6 /主函数中的结果,可见通过传值调用/a、b的 值并没有被“回带”面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第六十页,共八十四页2.2.传址调用的特点传址调用的特点 使用传址调用方式时,调用函数的实参是某个变量的地址值,被使用传址调用方式时,调用函数的实参是某个变量的地址值,被调用的函数的形参是指针(变量的指针或类类型的变量的指针)。调用的函数的形参是指针(变量的指针或类类型的变量的指针)。请请注意,不能通过注意,不能通过returnreturn返回或者通过参数返回或者通过参数“回带回带”在函数中定义的局部在函数中定义的局部变量的地址(或指针)。变量的地址(或指针)。例如,通过函数返回、指针参数和引用参数来得到函数中局部变量的例如,通过函数返回、指针参数和引用参数来得到函数中局部变量的值。下面的做法结果是错误的:值。下面的做法结果是错误的:int*f_pIntandInt(int*y,int&x)int*f_pIntandInt(int*y,int&x)int a=5;int a=5;int*s=&a;int*s=&a;y=s;/y=&a;y=s;/y=&a;x=a;x=a;return s;return s;面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第六十一页,共八十四页void main()void main()int a=6,b=7;int a=6,b=7;int*pa=&a;int*pa=&a;int*x=f_pIntandInt(pa,b);int*x=f_pIntandInt(pa,b);/执行完该语句后,变量的值将被改变执行完该语句后,变量的值将被改变cout”*x=“*xendl;cout”*x=“*xendl;cout”*pa=”*paendl;cout”*pa=”*paendl;cout”b=”bendl;cout”b=”bendl;运行结果如下:运行结果如下:*x=351*x=351/*x/*x不是不是5 5而是个随机数而是个随机数*pa=6*pa=6/*pa/*pa也不是也不是5 5且未被修改且未被修改 b=5 b=5/“/“回带回带”了值了值5 5面向对象程序设计面向对象程序设计面向对象程序设计面向对象程序设计 第二版第二版第二版第二版本讲稿第六十二页,共八十四页5.6.2引用调用 使用引用作为函数的形参时,调用函数的实参要使用引用作为函数的形参时,调用函数的实参要用变量名,将实参的变量名传给形参的引用,相当于,将实参的变量名传给形参的引用,相当于在被调用函数中使用了实参的别名。在被调用函数中使用了实参的别名。例如:交换两个变量例如:交换两个变量a a和和 b b的值。(采用引用调用)的值。(采用引用调用)void f_swap3(i