第4讲 函数的高级应用 主讲教师:资讯系 张玉宏.

Slides:



Advertisements
Similar presentations
2.8 函数的微分 1 微分的定义 2 微分的几何意义 3 微分公式与微分运算法则 4 微分在近似计算中的应用.
Advertisements

第8章 函数 信息管理系.
Oracle数据库 Oracle 子程序.
第14章 c++中的代码重用.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
Using C++ The Weird Way Something about c++11 & OOP tricks
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
授课老师:龚涛 信息科学与技术学院 2017年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
C语言程序设计基础 刘新国.
Object-Oriented Programming in C++ 第一章 C++的初步知识
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
《C++程序设计》 主讲教师:张玉宏.
走进编程 程序的顺序结构(二).
辅导课程六.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
第二章 Java语言基础.
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
临界区软件互斥软件实现算法 主讲教师:夏莹杰
参考书 《C++程序设计教程》 钱能 主编 清华大学出版社
第十章 模板 丘志杰 电子科技大学 计算机学院 软件学院.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
第七章 操作符重载 胡昊 南京大学计算机系软件所.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
第一章 函数与极限.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
顺序表的删除.
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
C++语言程序设计 第三章 函数.
第二章 Java基本语法 讲师:复凡.
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
Web安全基础教程
第五章 函 数 要点:掌握函数的定义,函数的原形,函数的返回值,函数的调用,函数的形式参数和实际参数之间的关系;掌握函数重载的使用方法,关键字inline的含义与使用,掌握变量的作用域与生存期,了解函数的作用域。
信号量(Semaphore).
第4章 Excel电子表格制作软件 4.4 函数(一).
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
3.16 枚举算法及其程序实现 ——数组的作用.
第二章 类型、对象、运算符和表达式.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第二章 高级函数特性.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第四章 函数 丘志杰 电子科技大学 计算机学院 软件学院.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
GIS基本功能 数据存储 与管理 数据采集 数据处理 与编辑 空间查询 空间查询 GIS能做什么? 与分析 叠加分析 缓冲区分析 网络分析
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二节 函数的极限 一、函数极限的定义 二、函数极限的性质 三、小结 思考题.
正弦、余弦函数的性质 华容一中 伍立华 2017年2月24日.
本节内容 结构体.
本章主題 C++的程式結構 資料型態與宣告 算術運算 簡易的輸入輸出指令 程式編譯(Compile)的過程與原理.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
C++语言程序设计教程 第4章 函数 第4章 函数.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
编译原理实践 6.程序设计语言PL/0.
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
计算机编程 信息管理与工程学院 2014年9月.
Presentation transcript:

第4讲 函数的高级应用 主讲教师:资讯系 张玉宏

1.函数重载( function Overloading) C++能提供函数重载的原因,是因为它是一种对数据类型(data type)的检查和控制非常严格的语言。对于编译器而言,只要参数不相同,不管是数目不一样还是数据类型不同,都视为不同的函数。 升达大学资讯系

1.函数重载( 续) 例如: int Max(int,int); 以及: 在程序中都可以因为调用函数所使用的参数不同而调用正确的函数。 float Max(float,float);//二者参数类型不同 以及: double Area(double x); double Area(double x,double y);//参数的数目不同 在程序中都可以因为调用函数所使用的参数不同而调用正确的函数。 升达大学资讯系

重载的例程 运 行 结 果 升达大学资讯系

函数的签名 C++要求重载的函数具有不同的签名(Signature)。函数的签名包括: 函数名 函数的参数个数、类型、顺序。 为了保证函数的唯一性,函数必须拥有独一无二的签名。 两个函数: int M(double,int); int M(int, double); 具有不同的函数签名,因为它们的参数的次序不同。 升达大学资讯系

函数的签名(续) 函数的数据返回类型不是函数的签名的一部分,所以重载函数不同通过返回值类型来加以区分。 例如: int a(int); double a(int); 不能相互区分,编译器将产生一条出错信息: ERROR:not distinct from s above 升达大学资讯系

2.函数默认参数 C++允许程序员以常数形式为函数参数设定默认值。如果在调用函数时不提供这个参数,则将使用这个默认值代替。例如,有一个函数Area(),它的第二个参数默认为12.0: 函数的声明为: float Area(float Width,float Length=12.0); 函数的定义为: float Area(float Width,float Length) {return Width*Length;} 如果调用时候没有写出第二个参数的值: A=Area(6.5);//只用一个参数调用 则会以默认值设定第二个参数,亦即A的值为:6.5*12.0 思考:为什么不可以认为Length的值是6.5,而Width还没有指定? 升达大学资讯系

2.函数默认参数(续) 默认值只能在函数的声明时指定或者是函数定义放在声明的位置的时候。但不可以同时在函数的声明式和定义式中指定。为了让编译器能正确区分,在参数列表中有默认值的参数必须放置在所有其他没有默认的参数的后边,不可以混杂。此外,在调用时,所有使用默认值的参数之后也必须使用默认值。例如,有一个函数的声明式为: void Func(float ,float x=0,int n=5,char =“r”) 则下面调用时正确的: Func(1.5); Func(3.2,1.0); Func(0.0,1.0,10,’a’); 而下面调用时错误的 Func(1.0,10,’a’);//类型不一致 也就是说函数调用的时候,实参和形参从左到右依次一一对应,若后面实参数量不够,则启用默认后面的默认函数参数。 升达大学资讯系

默认函数的例子 运行结果BC 运行结果VC #include <iomanip> using std::cout; // --- 声明函数Area() -------------------- float Area(float Width, float Length = 12.0); // --- 主程序 ---------------------------- int main(){ float A; A = Area(6.5); // 只用一个参数调用 cout << "A is : " << A; return 0;} // --- 定义函数Area() -------------------- float Area(float Width, float Length) { return Width*Length; } 运行结果BC 运行结果VC 升达大学资讯系

3.模板函数 3.1模板的引入 C++中加强了数据及函数类型的匹配检查,如果不慎写错一个变量名,编译器将帮助找出,从而加快错误定位和排除的速度。丰富的类型和严格的类型检查,大大方便了程序设计和排错。 但是丰富的类型和严格的类型检查,有时也会给我们带来一些麻烦。可能常常会遇到这样一种情况:对于很多数据类型,我们需要提供一种逻辑功能完全一样的函数,而编制这些函数提供的程序文本完全一样,其区别仅仅是处理的数据类型不同。 对于这种函数通常可以有两种实现方法,一种方法是使用宏函数,另一种方法是为各种类型都重载这一函数。但宏函数虽然方便,但是常常会引入一些意想不到的问题,因此C++中已经不提倡使用宏函数;而为各种数据类型重载有比较麻烦。模板函数就是适应这一要求而产生的。 升达大学资讯系

3.2模板函数的引入 模板函数(Function Template)是用来自动产生许多具有共同程序算法的函数的模板。这些函数将具有共同的逻辑和操作步骤,但其输入输出的数据类型可以不同。例如: template<class T> T Sum(T x,T y) {return x+y;} 相当于同时声明了很多名称都叫做Sum()的函数,但其输入输出类型未定,可以是int,float,double或char,真正的函数定义要由编译器判定实际使用的数据类型后才能完成。 上式中, template,class 都是C++的关键词。 template表示即将声明一个模板函数,而class 则用来声明以下模板函数所要使用的数据类型的暂定名称。理论上,任何名称都可以用来作为暂定的数据类型名称,但习惯都使用英文字母T。 注意:这里的模版数据类型class是指“用户定义的或固有的类型”,而字母T标识这个类型,这和即将讲到的类定义class是不相关的。虽然二者都是相同的关键词class 。 升达大学资讯系

3.2模板函数的引入(续) 模板函数(Function Template)是用来自动产生许多具有共同程序算法的函数的模板。这些函数将具有共同的逻辑和操作步骤,但其输入输出的数据类型可以不同。 例如: template<class T> T Sum(T x,T y) {return x+y;} 相当于同时声明了很多名称都叫做Sum()的函数,但其输入输出类型未定,可以是int,float,double或char,真正的函数定义要由编译器判定实际使用的数据类型后才能完成。 上式中, template,class 都是C++的关键词。 template表示即将声明一个模板函数,而class 则用来声明以下模板函数所要使用的数据类型的暂定名称。理论上,任何名称都可以用来作为暂定的数据类型名称,但习惯都使用英文字母T。 升达大学资讯系

模板函数的引入(续) 模板函数内可以列出多个参数,多个参数之间要用逗号隔开,而且每个参数都必须重复使用单词class,对所声明的参数数目没有限制。例如: template <class T1,class T2,class T3> T1 Func(T1 x,T2 y,T3 z) { //…函数内容 } 当然,这些参数名( T1,T2,T3)的作用域仅仅存在于该模板范围之内。建议最好使用描述性的参数名,并且使用以T开头的标识符以提醒我们注意它们的模板状态。如: template<class TData,class Tindex); 升达大学资讯系

模板函数的例程 模板函数内可以列出多个参数,多个参数之间要用逗号隔开,而且每个参数都必须重复使用单词class,对所声明的参数数目没有限制。例如: template <class T1,class T2,class T3> T1 Func(T1 x,T2 y,T3 z) { //…函数内容 } 当然,这些参数名( T1,T2,T3)的作用域仅仅存在于该模板范围之内。建议最好使用描述性的参数名,并且使用以T开头的标识符以提醒我们注意它们的模板状态。如: template<class TData,class Tindex); 升达大学资讯系

template <class T> T max(T x,T y){return (x>y)?(x):(y);} //模板函数形同一群重载函数的定义。 #include <iostream.h> void main() { int x=3,y=4; double a=1.2 ,b=2.6; cout<<max(x,y)<<endl;//调用模板函数int(int,int) cout<<max(a,b)<<endl; //调用模板函数double(double, double) } 说明:函数模板里面必须包含完整的内容,只是数据类型暂时还不确定罢了。置放模板函数的位置和函数原形相同,都位于主程序之前 升达大学资讯系

4.函数与引用 C++中,在默认的情况下,当函数返回一个值时: return expression ; expression 被求出值,并将该值拷贝到临时存储空间,以便函数调用者访问。这种返回方式称为传值调用(return by value)<详见第三讲>。 例:当调用如下函数 int val1(){ … //函数的主体 return i; } 这时i的值将被拷贝到临时存储空间,调用者获得是i的一个副本.也就是说,如果有调用函数: j=val1(); 升达大学资讯系

4.函数与引用(续) 临时存储空间 8 i j 拷贝到 则将i的值拷贝到临时空间,然后再拷贝到j。如下图所示 函数返回值还有另一种方式,即引用返回(return by reference).在这种情况下,返回值不再拷贝到临时存储空间,甚至连return语句所用的那个存储单元对调用者来说都是可访问的。引用返回的语法是在返回类型前加一个标记“&”. 升达大学资讯系

4.函数与引用(续) 8 i j 拷贝到 例:假设有一个函数定义如下: int& val2(){ … //函数的主体 return i;} 由于上述函数的返回类型为int& ,因此是引用返回。当return 语句执行后,调用者可以直接访问i.例如,以下方式调用函数val2(): j=val2(); 则将i的值直接拷贝到j中,如下图所示: 8 i j 拷贝到 升达大学资讯系

4.函数与引用(续) 例:很多程序员习惯从1开始的数组,如下函数则可以实现访问从0开始的数组,其方式对于程序员来说是访问从1开始的。该函数以I为索引访问整型数组a,其中是从1开始的,同过减1操作,寒暑内部实际是以C++方式(即从0开始索引)访问该数组。函数返回的是数组元素的引用。 int& new_index(int a[],int i){ return a[i-1]; } int& 标记表明函数的返回类型是int型的引用,返回的是实际单元a[i-1],而不是其副本。可用如下方式调用函数new_index: val=new_index(a,8);//返回的是第8个数组元素 升达大学资讯系

4.函数与引用(续) 回头看看 -16被保存在数组第8个单元中即a[7]中 使用引用返回的一个好处是:如果一个函数以引用方式返回,则这个函数调用可出现在赋值语句的左边。例如以下为对函数new_index的合法调用: new_index(a,8)=-16; 其含义是: -16被保存在数组第8个单元中即a[7]中 由于使用引用的函数返回的是一个实际单元,所以必须保证函数返回时该单元仍然有效。也就是说在定义引用的函数时,注意不要对该函数内的自动变量的引用。不然的话,因为自动变量的生存期仅限于函数内部,当函数返回时,自动变量就消失了,函数就会返回一个无效的引用。 升达大学资讯系

4.函数引用的一个例子 运行结果 #include<iostream.h> int a[]={2,4,6,8,10,12}; int& index(int i);//引用函数的声明 void main(){ cout<<"原来a[3]的值为:"<<a[3]<<endl; index(3)=16; cout<<"执行index(3)=16后a[3]的值为:"<<a[3]<<endl; cout<<“执行index(3)=16后index(3)的值为:"<<index(3)<<endl; } //================引用函数的定义=========== int& index(int i){return a[i];} 升达大学资讯系

4.函数引用的另一个例子 函数: int& f(){ int i; //… //…*****ERROR:i goes out of existence rerutrn i; } 上述语句包含一个错误。当函数f()返回i时,i已经不存在了(因为i是局部变量)。因此,函数调用者不能访问传回的i。 纠正上述错误的两种方法: 1.改为传值调用,此时i的值被拷贝到临时空间中,函数调用者从临时变量中访问该临时变量。 2.将i声明为全局变量,则I的值不会因为f()的调用结束而结束 升达大学资讯系