第6讲函数2297205094.ppt

上传人:本田雅阁 文档编号:2500645 上传时间:2019-04-04 格式:PPT 页数:28 大小:851.01KB
返回 下载 相关 举报
第6讲函数2297205094.ppt_第1页
第1页 / 共28页
第6讲函数2297205094.ppt_第2页
第2页 / 共28页
第6讲函数2297205094.ppt_第3页
第3页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第6讲函数2297205094.ppt》由会员分享,可在线阅读,更多相关《第6讲函数2297205094.ppt(28页珍藏版)》请在三一文库上搜索。

1、第六讲 函数(2),清华大学 郑 莉,教材:C+语言程序设计(第4版)第3章 3.23.7,目录,6.1 内联函数 6.2 带缺省形参值的函数 6.3 函数重载 6.4 使用C+系统函数 6.5 深度探索 6.6 小结,2,6.1 内联函数,声明时使用关键字 inline。 编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。 注意: 内联函数体内不能有循环语句和switch语句。 内联函数的声明必须出现在内联函数第一次被调用之前。 对内联函数不能进行异常接口声明。,3,例6-1(教材例3-14 ) 内联函数应用举例,#include using namespace std; co

2、nst double PI = 3.14159265358979; inline double calArea(double radius) return PI * radius * radius; int main() double r = 3.0; double area = calArea(r); cout area endl; return 0; ,4,6.1 内联函数,6.2 带缺省形参值的函数,函数在声明时可以预先给出缺省的形参值,调用时如给出实参,则采用实参值,否则采用预先给出的缺省形参值。 例如: int add(int x = 5,int y = 6) return x +

3、y; int main() add(10,20);/10+20 add(10); /10+6 add(); /5+6 ,5,缺省形参值的说明次序,有缺省参数的形参必须在形参列表的最后,也就是说缺省形参值的右面不能有无缺省值的参数。因为调用时实参与形参的结合是从左向右的顺序。 例: int add(int x, int y = 5, int z = 6);/正确 int add(int x = 1, int y = 5, int z);/错误 int add(int x = 1, int y, int z = 6);/错误,6,6.2 带缺省形参值的函数,缺省形参值与函数的调用位置,如果一个函数

4、有原型声明,且原型声明在定义之前,则缺省形参值必须在函数原型声明中给出;而如果只有函数的定义,或函数定义在前,则缺省形参值需在函数定义中给出。 例:,7,6.2 带缺省形参值的函数,int add(int x = 5,int y = 6) /只有定义,没有原型声明 return x + y; int main() add(); ,int add(int x = 5,int y = 6); /原型声明在前 int main() add(); int add(int x,int y) /此处不能再指定缺省值 return x + y; ,例6-2(教材例3-15) 计算长方体的体积,子函数getV

5、olume是计算体积的函数,有三个形参:length(长)、width(宽)、height(高),其中width和height带有缺省值。 主函数中以不同形式调用getVolume函数,分析程序的运行结果。,8,6.2 带缺省形参值的函数,#include #include using namespace std; int getVolume(int length, int width = 2, int height = 3); int main() const int X = 10, Y = 12, Z = 15; cout “Some box data is “ ; cout getVol

6、ume(X, Y, Z) endl; cout “Some box data is “ ; cout getVolume(X, Y) endl; cout “Some box data is “ ; cout getVolume(X) endl; return 0; int getVolume(int length, int width/* = 2 */, int height/* = 3 */) cout setw(5) length setw(5) width setw(5) height t; return length * width * height; ,9,6.2 带缺省形参值的函

7、数,例6-2(续),6.3 函数重载,C+允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。 例:,10,注意事项,11,6.3 函数重载,不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。这样不好:,重载函数的形参必须不同:个数不同或类型不同。 编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。,例6-3(教材例3-16) 重载函数应用举例,编写两个名为sumOfSquare的重载函数,分别求两整数的平方和及两实数的平方和。,12,6.3 函数重载,#include using namespace std; int sum

8、OfSquare(int a, int b) return a * a + b * b; double sumOfSquare(double a, double b) return a * a + b * b; int main() int m, n; cout m n; cout x y; cout “Their sum of square: “ sumOfSquare(x, y) endl; return 0; ,13,6.3 函数重载,例6-3(续),运行结果: Enter two integer: 3 5 Their sum of square: 34 Enter two real n

9、umber: 2.3 5.8 Their sum of square: 38.93,例6-3(续),6.3 函数重载,6.4 使用C+系统函数,C+的系统库中提供了几百个函数可供程序员使用。 例如:求平方根函数(sprt)、求绝对值函数(abs)等。 使用系统函数时要包含相应的头文件。 例如:cmath 或 math.h,15,例6-4(教材例3-17) 系统函数应用举例,题目: 从键盘输入一个角度值,求出该角度的正弦值、余弦值和正切值。 分析: 系统函数中提供了求正弦值、余弦值和正切值的函数:sin()、cos()、tan(),函数的说明在头文件cmath中。,16,6.4 使用C+系统函数

10、,#include #include using namespace std; const double PI = 3.14159265358979; int main() double angle; cout angle; /输入角度值 double radian = angle * PI / 180; /转化为弧度值 cout “sin(“ angle “) = “ sin(radian) endl; cout “cos(“ angle “) = “ cos(radian) endl; cout “tan(“ angle “) = “ tan(radian) endl; return 0;

11、 ,17,6.4 使用C+系统函数,运行结果: 30 sin(30)=0.5 cos(30)=0.866025 tan(30)=0.57735,例6-4(续),标准函数与非标准函数,标准C+函数 C+标准中规定的函数; 各种编译环境普遍支持,因此用标准函数的程序移植性好; 很多标准C+函数继承自标准C,头文件以c开头:cmath,cstdlib,cstdio,ctime 非标准C+函数 与特定操作系统或编译环境相关; 在处理和操作系统相关事务时常常需要调用。,18,6.4 使用C+系统函数,查找系统函数的使用说明,查编译系统的库函数手册 查联机帮助Visual C+.NET 2008联机帮助的

12、使用方法: 进入MSDN Library for Visual Studio 2008 Development Tools and Languages - Visual Studio - Visual C+ - Reference - Libraries Reference -Run-Time Library - Run-Time Routines by Category,19,6.4 使用C+系统函数,6.5.1运行栈与函数调用的执行 形参和局部变量的存储,为什么不能为形参和局部变量分配固定地址? 他们仅在函数调用时生效,函数返回后即失效,分配固定地址造成空间浪费 更重要的是,发生递归调用时

13、,多次调用间的形参和局部变量应彼此独立 需要栈式存储,20,6.5 深度探索,栈,栈是一种容纳数据的容器 数据只能从栈的一端存入(压入栈) 数据只能从栈的同一端取出(弹出栈),21,6.5 深度探索 6.5.1 运行栈与函数调用的执行,运行栈,运行栈是一段区域的内存空间 运行栈分为一个一个栈帧 每个栈帧对应一次函数调用 栈帧中包括: 本次函数调用的形参值 控制信息 局部变量值 一些临时数据 函数调用时,会一个栈帧被压入运行栈 返回时,会有一个栈帧被弹出,22,6.5 深度探索 6.5.1 运行栈与函数调用的执行,运行栈示意图,unsigned fac(unsigned n) unsigned

14、f; if (n = 0) f = 1; else f = fac(n - 1) * n; return f; int main() unsigned n; cin n; unsigned y = fac(n); ,23,6.5 深度探索 6.5.1 运行栈与函数调用的执行,函数调用的执行过程,栈指针esp:指向运行栈栈顶 帧指针ebp:定位形参和局部变量 传递参数:调用前把实参压入堆栈 函数调用时的几步关键操作 call指令:将下一条指令地址(返回地址)压入运行栈,转到函数入口地址 被调函数入口处:将当前ebp压入运行栈,用ebp保存esp,调整esp为局部变量留出空间 被调函数出口处:用e

15、bp恢复esp,从运行栈中弹出ebp原值 ret指令:将返回地址从运行栈弹出,转到返回地址,24,6.5 深度探索 6.5.1 运行栈与函数调用的执行,运行栈的数据分布,unsigned fac(unsigned n) unsigned f; if (n = 0) f = 1; else f = fac(n - 1) * n; return f; ,25,6.5 深度探索 6.5.1 运行栈与函数调用的执行,形参和局部变量定位: ebp 8:形参n ebp + 4:局部变量f,6.5.2 函数声明与类型安全,以错误方式调用函数的危险性 函数的原型信息(参数个数和类型、返回值类型)在编译后即不存

16、在; 如果不要求声明函数,以错误的方式(错误的参数数量或类型)调用函数,会产生不可预期的结果,但很多情况下不会给出错误提示。 函数原型是主调函数与被调函数间的协议 运行结果错误 vs 编译错误 一个错误,与其被淹没在运行中,不如暴露在编译时。,26,6.5 深度探索,C语言的反例,27,6.5 深度探索 6.5.2 函数声明与类型安全,C语言允许 只声明函数名和返回类型,而不声明参数类型 不声明函数,直接调用 后果:隐蔽错误 如果给出add()的完整声明,则会自动进行类型转换。 声明带来了类型安全,double add(); int main() double s = add(1, 2); . return 0; double add(double a, double b) return a + b; ,6.6 小结,主要内容 内联函数、带默认形参值的函数、函数重载、C+系统函数 达到的目标 学会将一段功能相对独立的程序写成一个函数,为下一讲学习类和对象打好必要的基础。,28,

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1