面向对象的程序设计语言——C++ 第二版 教学课件 ppt 作者 陈志泊 第04章

上传人:E**** 文档编号:89457120 上传时间:2019-05-25 格式:PPT 页数:65 大小:394KB
返回 下载 相关 举报
面向对象的程序设计语言——C++ 第二版  教学课件 ppt 作者  陈志泊 第04章_第1页
第1页 / 共65页
面向对象的程序设计语言——C++ 第二版  教学课件 ppt 作者  陈志泊 第04章_第2页
第2页 / 共65页
面向对象的程序设计语言——C++ 第二版  教学课件 ppt 作者  陈志泊 第04章_第3页
第3页 / 共65页
面向对象的程序设计语言——C++ 第二版  教学课件 ppt 作者  陈志泊 第04章_第4页
第4页 / 共65页
面向对象的程序设计语言——C++ 第二版  教学课件 ppt 作者  陈志泊 第04章_第5页
第5页 / 共65页
点击查看更多>>
资源描述

《面向对象的程序设计语言——C++ 第二版 教学课件 ppt 作者 陈志泊 第04章》由会员分享,可在线阅读,更多相关《面向对象的程序设计语言——C++ 第二版 教学课件 ppt 作者 陈志泊 第04章(65页珍藏版)》请在金锄头文库上搜索。

1、第4章,函数,2,关于函数,一个C+程序是由若干个源程序文件(.cpp文件)构成的,而一个源程序文件是由若干个函数构成的。 利用函数的目的有两个方面: 一方面使程序更利于维护、逻辑上更加清晰; 另一方面对于某些相同的功能,可以通过多个函数调用完成该功能的多次实现,从而减少重复性代码的编写工作。,3,本章主要内容,(1)熟练掌握函数定义及其调用的方法和形式。 (2)理解和领会函数重载的意义,并可以根据需求进行函数的重载。 (3)理解C+提供的3种预处理命令:宏定义命令、文件包含命令和条件编译命令。 (4)理解和掌握全局变量和局部变量的定义、生存周期以及作用域。,4,4.1 函数的定义,4.1.1

2、 函数的定义 从用户的角度看,有两种不同的函数。 库函数也称标准函数,它是由C+系统提供的,用户不必自己定义便可在程序中直接使用; 用户自定义函数则需要用户根据程序的要求进行定义后,才可在程序中进行使用。 定义函数的一般形式: 函数返回值的数据类型标识符 函数名(形式参数表) 函数体 ,5,如: void display_larger( int x, int y) if (xy) cout“The larger is : “x“n“; else cout“Two values are equal. “n“; ,6,说明: (1) “函数返回值的数据类型标识符”表示该函数返回值的类型,“函数名”

3、即函数的名称,由用户给定,命名和变量名的命名规则相同,“形式参数”(即形参)的书写形式要采用新的ANSI标准,即必须把形参放在函数名后面的括号内,每个参数由参数类型和参数名构成。 (2)当形参有多个时,各参数间必须用逗号隔开。 (3)如果函数是无参函数,则函数名后面的括号不能省略。 (4)所有的函数都要先定义、后使用(调用)。 (5)不能省略函数值的类型,而必须表明该函数返回的函数值的类型。当该函数没有返回值时,函数返回值的类型要写成void。 (6)函数体由在一对花括号中的若干条语句组成,C+不允许在一个函数体内再定义另一个函数,即不允许在一个函数体的内部再定义另外一个函数,所有函数的定义必

4、须是平等的、独立的。,7,4.1.2 函数的参数,调用函数是指在程序中使用了该函数。 如果在一个程序中有函数A和B,并且在函数A中使用了函数B,则称函数A调用了函数B。 函数A称为主调函数。 函数B称为被调函数。 在函数A中进行调用函数B的那条语句称为调用点。,8,大多数情况下,在调用函数时,主调函数和被调函数之间有数据传递关系。 函数之间的数据传递就是靠函数的参数进行的,这就是前面提到的有参函数(无参函数没有数据传递)。 在定义函数时,函数名后面括号内的变量名为“形式参数”(形参)。 在调用函数时,函数名后面括号内的表达式为“实际参数”(实参)。,9,【例4-1】输入两个整数,并显示最大值。

5、 关于形参和实参有以下几点说明: (1)在定义一个有参函数时指定的形参变量,在未发生函数调用时并不占存储单元,只有存在发生函数调用时形参才被分配存储单元,在调用结束后,形参所占的内存单元被释放。 (2)实参可以是变量、常量或表达式,但必须有确定的值;而形参必须是变量。,10,(3)实参与形参的类型必须一致,否则会发生“类型不匹配”的情况。 (4)实参对形参的数据传递是“值传递”,即单向传递。只能由实参把数据传给形参,并且存储单元与形参是不同的单元,所以只能将实参对应的值依次传递给形参变量。调用结束后,形参单元被释放,而实参单元保留并维持原值。,11,4.1.3 函数的返回值,通常通过调用某一函

6、数得到一个确定的值,这就是函数的返回值。 说明: (1)函数的返回值是通过函数体中的return语句获得的,return语句将被调用函数中的一个确定的值带回主调函数中。return语句的格式为: return(表达式); 或 return 表达式; 如: int max(int a,int b) return(ab?a:b);,12,(2)函数值的类型 在定义函数时,当函数值说明的类型和return语句中的表达式类型不一致时,则以函数类型为准。 (3)如果被调用函数中没有return语句,则该函数不带回用户所希望得到的一个确定的函数值,但实际上,函数并不是不带回值,只是带回的是一个不确定的值,

7、为了明确表示函数“不返回值”,可以用void定义无类型。 如: void print() cout“c language“; 这样,系统就保证不使函数print带回任何值。,13,(4)return语句可以出现在程序的任何位置。一旦执行了return语句,则意味着被调函数执行结束,需要返回到主调函数,此时return语句后面的所有语句都不会被执行。,14,4.2 函数的调用,4.2.1 函数的调用形式 1函数调用形式 函数名(实参列表) 如果程序中调用的是无参函数,则实参列表可略去,但函数的括号不能省; 如果实参表中有多个参数,则它们之间用逗号隔开; 实参的类型、个数应与形参顺序一一对应。,1

8、5,函数通过下列3种方式完成函数调用: (1)函数调用语句:如printf(); (2)函数表达式:如c=2*max(a,b); (3)函数参数:如m=max(a,max(b,c);,16,2函数调用的执行过程 一个C+程序经过编译以后生成可执行的程序代码,形成的程序文件名的后缀是.exe,存放在外存储器中,如硬盘等。 程序运行被启动时,系统首先从外存储器上将可执行程序文件代码装载到内存的代码区,然后从入口地址(即main函数的起始处)开始执行。,17,程序在执行过程中,如果遇到了对其他函数的调用,则暂停当前函数的执行,保存下一条指令的地址(即返回地址,作为从被调函数返回后继续执行的入口点),

9、并保存现场,然后转到被调函数的入口地址,执行被调函数。 当遇到return语句或者被调函数执行结束时,则恢复先前保存的现场,并从先前保存的返回地址开始继续执行主调函数的其余部分。,18,【例4-1】函数的调用执行过程。,main函数,调用max函数,执行结束,保存返回地址当前现场,max函数,恢复主调函数的现场返回地址,返回,19,3调用函数时的前提条件 在一个函数中调用另一个函数,需要具备的条件有以下几点: (1)首先被调用的函数必须是已经存在的函数。 如果调用库函数,一般应在本文件的开头用#include命令将调用有关库函数时所需用到的信息包含到本文件中。 如果调用用户自己定义的函数,则必

10、须对被调函数的原型进行说明。 函数类型 函数名(参数类型1, 参数类型2, ) 函数类型 函数名(参数类型1 参数名1, 参数类型2 参数名2,),20,(2)对函数原型的说明可以放在程序的顶部,也可以放在主调函数体的内部。 通常对程序中需要调用的所有函数的说明存放到一个头文件(.h文件)中,然后利用#include命令将其嵌入到程序中; 这样,程序就可以任意调用各个函数,不必再关心哪个被调函数是否已经进行了说明。,21,(3)如果在程序中被调函数的定义出现在主调函数的前面时,可以省略对被调函数的说明。 通常在程序的首部需要对本程序中所有已定义的函数都进行说明,以便程序中对这些函数进行调用。,

11、22,4函数定义与函数说明间的区别 (1)函数的“定义” 是指一个函数功能的确立包括指定函数名、函数返回值的类型、形参及其类型、函数体等。 它是一个完整的、独立的函数单位。,23,(2)函数的“说明” 只是对已经定义好的函数的返回值进行类型的说明。 它包括函数名、函数类型和形参及其类型,而不包括函数体。 函数说明的作用是告诉系统,在本函数中将要用到的函数是什么类型,也就是说明该函数的返回值的类型,以便在主调函数中按此类型对函数值作相应的处理。 函数说明中也可以不必指出形参列表中的变量名,但是必须要指出每个参数的数据类型。,24,4.2.2 函数的嵌套调用,在C+语言中,函数的定义是平行的、独立

12、的,即在定义一个函数时,其内部不能再包含另一个函数的定义。 所以,函数的定义是不能嵌套进行的,但函数的调用是可以的。 嵌套调用就是在调用一个函数的过程中又调用另一个函数,如图4-2所示。,25,26,4.2.3 函数的递归调用,1函数递归调用的概念 函数的递归调用就是当一个函数在执行的过程中出现了直接或间接地调用函数本身的函数调用方式。 如果是直接调用函数本身,则称为直接递归; 如果是通过调用另外一个函数间接调用本身,则称为间接递归,即函数的嵌套调用是函数本身。,27,函数的递归调用应该说是函数的嵌套调用的特殊形式。 下面定义求n!的函数。 long fact(long n) if (n= =

13、0) return 1; return fact(n-1)*n; ,28,在正确理解函数的递归调用时,可以认为,每当递归调用一次函数本身,就相当于产生了该函数的一个副本(就相当于是另外一个函数),直到最后一次递归调用结束,程序执行的流程返回到倒数第二次递归调用函数的调用点处。 依次类推,直到返回到最初一次的函数调用点处。 由此可见,完全可以利用对函数嵌套调用机理的理解方式去理解递归调用的机理。,29,2函数递归调用的条件 (1)必须有完成函数任务的语句。如上例中的return 1。 (2)有一个确定是否能避免递归调用的测试条件。如上例中的if(n= =0)就是一个测试。如果条件不满足时就递归调

14、用;否则就不再递归调用。 (3)有一个递归调用语句,并且该递归调用语句的参数应该逐渐逼近不满足条件,以致最后断绝递归。 (4)先测试、后递归调用。在递归函数定义中,必须先测试、后递归调用。也就是说,递归是有条件的,满足了条件后才可以递归。,30,递归的过程有两个阶段: 第一阶段:递推。 如,求3!,可以这样分解: 3!=32!2!=21!1!=10!0!=1,未知,已知,第二阶段:回归 3!=32!=62!=21!=21!=10!=10!=1,未知,已知,【例4-2】任意输出一个大于或等于0的整数n(n3),求其阶乘n!,31,4.3 内联函数,4.3.1 内联函数的定义方法 为了提高程序运行

15、速度,节省开销,C+中提供了一种在编译时可将所调用函数的代码直接嵌入主调函数中的方法,这种嵌入到主调函数中的函数称为内联函数。 内联函数的定义方法和格式为: inline 函数值的类型 函数名(形参及其类型列表) 函数体 ,32,如: inline double square(double x) return x*x; void main() double x; coutx; cout“the squre is”square(x); ,33,4.3.2 内联函数与普通函数的区别和联系,(1)在定义内联函数时,函数值的类型左面有“inline”关键字。 (2)程序中调用内联函数与普通函数的方式和

16、方法相同。 (3)当在程序中调用一个内联函数时,是将该函数的代码直接插入到调用点,然后执行该段代码,所以,在调用过程中不存在程序流程的跳转和返回问题; (4)从调用机理看,内联函数可加快程序代码的执行速度和效率,减少调用开销。但这是以增加程序代码为代价来换取速度的。,34,4.3.3 对内联函数的限制,注意:不是任何一个函数都可定义成内联函数。 (1)内联函数的函数体内不能含有复杂的结构控制语句,如switch和while等。如果内联函数的函数体内有这些语句,则编译将该函数视同普通函数那样产生函数调用代码。 (2)递归函数不能被用来作为内联函数。 (3)内联函数一般适合于只有15行语句的小函数,对于一个含有很多语句的大函数,函数调用和返回的开销相对来说是微不足道的,所以,也没有必要用内联函数来实现。,35,4.4 带默认形参值的函数,4.4.1 默认参数的函数 在C中,调用函数时的实参的个数、类型、顺序都必须与被调函数的形参的个数、类型、顺序保持

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号