C++语言程序设计 第三章 函数.

Slides:



Advertisements
Similar presentations
6.4 字符串与指针 1. 用字符数组存放一个字符串.
Advertisements

VC++系统开发 第二章 C++语言基础 河北经贸大学信息技术学院.
第14章 c++中的代码重用.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
Using C++ The Weird Way Something about c++11 & OOP tricks
第8讲 函数 8.1 函数的定义与调用 8.2 函数的参数 8.3 函数重载与递归 8.4 标识符作用域与变量的存储特性.
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
第5章 函数与预处理 《 C语言程序设计》 (Visual C++ 6.0环境) 本章导读
第八章 函数 §8.1 概述 一个较大程序一般分为若干个程序模块,每一个模块实现一个特定的功能。所有的高级语言中都有子程序的概念,在C中子程序就是函数。 一个C程序可由一个主函数和若干个函数构成,由主函数调用其它函数,其它函数也可以相互调用.
函數(一) 自訂函數、遞迴函數 綠園.
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C语言程序设计基础 刘新国.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Function.
Object-Oriented Programming in C++ 第一章 C++的初步知识
程序设计期末复习 黎金宁
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
管理信息结构SMI.
走进编程 程序的顺序结构(二).
辅导课程六.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
第二章 C++对C 在非面向对象方面的改进 更简洁,更安全.
第五章 函 数. 第五章 函 数 教学目标 (1) 了解函数在程序设计中的作用; (2) 掌握函数的定义方法; (3) 掌握函数调用和参数传递的机制和方法; (4) 了解变量的作用域和生存期的概念。
第一章 C++基础.
C++语言程序设计 第二章 C++简单程序设计.
参考书 《C++程序设计教程》 钱能 主编 清华大学出版社
第七章 操作符重载 胡昊 南京大学计算机系软件所.
第2章 C++流程控制语句 if 语句 switch语句 for语句 while语句 do - while语句 break语句
第一章 函数与极限.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
C++语言程序设计 C++语言程序设计 第五章 函数 第十一组 C++语言程序设计.
$9 泛型基础.
程式結構&語法.
C++语言程序设计 第三章 函数 清华大学 郑 莉.
C语言程序设计.
目录 7.1 用户自定义函数的种类 7.2 函数的定义 7.3 被调函数的声明 7.4 函数的调用 7.5 函数的嵌套调用
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第五章 函 数 要点:掌握函数的定义,函数的原形,函数的返回值,函数的调用,函数的形式参数和实际参数之间的关系;掌握函数重载的使用方法,关键字inline的含义与使用,掌握变量的作用域与生存期,了解函数的作用域。
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C程序设计.
第4章 Excel电子表格制作软件 4.4 函数(一).
第九节 赋值运算符和赋值表达式.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第二章 高级函数特性.
挑戰C++程式語言 ──第9章 函數.
第二章 Java基本语法 讲师:复凡.
第四章 函数 丘志杰 电子科技大学 计算机学院 软件学院.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
本章主題 C++的程式結構 資料型態與宣告 算術運算 簡易的輸入輸出指令 程式編譯(Compile)的過程與原理.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第三章 高级函数特性.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
C++语言程序设计教程 第4章 函数 第4章 函数.
第9章 C++程序设计初步 9.1 C++的特点 9.2 最简单的C++程序 9.3 C++的输入输出 9.4 函数的重载
變數與資料型態  綠園.
本节内容 this指针 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
计算机编程 信息管理与工程学院 2014年9月.
Presentation transcript:

C++语言程序设计 第三章 函数

本章主要内容 函数的声明和调用 函数间的参数传递 引用 内联函数 带缺省形参值的函数 函数重载 函数模板 C++系统函数

函数的定义 函数的声明与使用 函数是面向对象程序设计中的基本抽象单元,是对功能的抽象 函数定义的语法形式 类型标识符 函数名(形式参数表) 类型标识符 函数名(形式参数表) { 语句序列 } 若无参数,写void 是被初始化的内部变量,寿命和可见性仅限于函数内部 若无返回值,写void

函数的定义 函数的声明与使用 形式参数表 <type1> name1, <type2> name2, ..., <typen> namen 函数的返回值 由 return 语句给出,例如: return 0 无返回值的函数(void类型),不必写return语句。

函数的调用 函数的声明与使用 调用前先声明函数原型: 在调用函数的说明部分,或程序文件开头所有函数之前,按如下形式说明: 类型标识符 被调用函数名 (含类型说明的形参表); 调用形式 函数名(实参列表) 实参列表中应给出与函数原型形参个数相同、类型相符的实参。 嵌套调用 函数不允许嵌套定义(定义一个函数时,函数体内又包含另一个函数的完整定义,叫嵌套定义)。 可以嵌套调用。 递归调用 函数直接或间接调用自身。

例3-1 编写一个求x的n次方的函数 函数的声明与使用 #include <iostream.h> double power (double x, int n); void main(void) { cout << "5 to the power 2 is " << power(5,2) << endl; } double power (double x, int n) double val = 1.0; while (n--) val = val*x; return(val);

例3-1 编写一个求x的n次方的函数 函数的声明与使用 运行结果: 5 to the power 2 is 25

例3-3 编写程序求π的值 函数的声明与使用 其中arctan用如下形式的级数计算: 直到级数某项绝对值不大于10-15为止;π和x均为double型。

#include<iostream.h> void main( ) { double a,b; double arctan(double x) ; a=16.0*arctan(1/5.0) ; b=4.0*arctan(1/239.0) ; //注意:因为整数相除结果取整, //如果参数写1/5,1/239,结果就都是0 cout<<"PI="<<a-b<<endl; }

运行结果: PI=3.14159 double arctan(double x) { int i; double r,e,f,sqr; sqr=x*x; r=0; e=x; i=1; while(e/i>1e-15) { f=e/i; r=(i%4==1)? r+f : r-f ; //i=1,5,9,13,…… e=e*sqr; i+=2; } return r ; 运行结果: PI=3.14159

运行结果: PI=3.14159

例3-4 函数的声明与使用 寻找并输出11~999之间的数m,它满足m、m2和m3均为回文数。 分析: 回文:各位数字左右对称的整数。 例如:11满足上述条件 112=121,113=1331。 分析: 10取余的方法,从最低位开始,依次取出该数的各位数字。按反序重新构成新的数,比较与原数是否相等,若相等,则原数为回文。

#include <iostream.h> void main( ) { bool symm(long n); long m; for(m=11; m<1000; m++) if (symm(m)&&symm(m*m)&&symm(m*m*m)) cout<<"m="<<m<<" m*m="<<m*m<<" m*m*m="<<m*m*m<<endl; }

bool symm(long n) { long i, m; i=n ; m=0 ; while(i) m=m*10+i%10; i=i/10 ; } return ( m==n );

运行结果: m=11 m*m=121 m*m*m=1331 m=101 m*m=10201 m*m*m=1030301 m=111 m*m=12321 m*m*m=1367631

函数调用的执行过程 函数的声明与使用 main( ) 调fun( ) 结束 ① ② ④ ⑥ ⑦ ③ ⑤ 保存: 返回地址 fun( ) 当前现场 ③ 恢复: 主调程序现场 ⑤

嵌套调用 函数的声明与使用 main{} 调fun1( ) 结束 fun1( ) 调fun2( ) 返回 fun2( ) 返回 ① ② ③ ④ ⑤ ⑨ ⑦ ⑧ ⑥

例3-7 输入两个整数,求平方和。 函数的声明与使用 #include <iostream.h> void main(void) { int a,b; int fun1(int x,int y); cin>>a>>b; cout<<"a、b的平方和:" <<fun1(a,b)<<endl; }

int fun1(int x,int y) { int fun2(int m); return (fun2(x)+fun2(y)); } int fun2(int m) return (m*m); 运行结果: 3 4 a、b的平方和:25

递归调用 函数的声明与使用 函数直接或间接地调用自身,称为递归调用。 递归过程的两个阶段: 递推: 未知 已知 回归: 4!=4×3! → 3!=3×2! → 2!=2×1! → 1!=1×0! → 0!=1 未知 已知 回归: 4!=4×3!=24←3!=3×2!=6←2!=2×1!=2←1!=1×0!=1←0!=1 未知 已知

例3-8 求n! 函数的声明与使用 分析:计算n!的公式如下: 这是一个递归形式的公式,应该用递归函数实现。

源程序: #include <iostream.h> long fac(int n) { long f; if (n<0) cout<<"n<0,data error!"<<endl; else if (n==0) f=1; else f=fac(n-1)*n; return(f); }

void main( ) { long fac(int n); int n; long y; cout<<"Enter a positive integer:"; cin>>n; y=fac(n); cout<<n<<"!="<<y<<endl; } 运行结果: Enter a positive integer:8 8!=40320

函数的参数传递机制 ——传递参数值 函数的声明与使用 在函数被调用时才分配形参的存储单元。 实参可以是常量、变量或表达式。 函数的参数传递机制 ——传递参数值 函数的声明与使用 在函数被调用时才分配形参的存储单元。 实参可以是常量、变量或表达式。 实参类型必须与形参相符。 传递时是传递参数值,即单向传递。

函数的参数传递机制 ——参数值传递举例 函数的声明与使用 X N 被调函数: 主调函数: 3 2.5 A D = power(A,3) 函数的参数传递机制 ——参数值传递举例 函数的声明与使用 X N 被调函数: 主调函数: 3 2.5 A D = power(A,3) double power(double X, int N)

例3-11 输入两 整数交换后输出 函数的声明与使用 #include<iostream.h> void Swap(int a, int b); int main( ) { int x(5), y(10); cout<<"x="<<x<<" y="<<y<<endl; Swap(x,y); return 0; } 交换函数 Swap 采用值传递,未达到交换效果。

void Swap(int a, int b) { int t; t=a; a=b; b=t; } 运行结果: x=5 y=10

函数的参数传递 ——用引用做形参 函数的声明与使用 引用(&)是标识符的别名,例如: 函数的参数传递 ——用引用做形参 函数的声明与使用 引用(&)是标识符的别名,例如: int i,j; int &ri=i; //建立一个int型的引用ri,并将其 //初始化为变量i的一个别名 j=10; ri=j;//相当于 i=j; 声明一个引用时,必须同时对它进行初始化,使它指向一个已存在的对象。 一旦一个引用被初始化后,就不能改为指向其它对象。 引用可以作为形参 void swap(int& a, int& b) {...}

例3-12 输入两个整数交换后输出 函数的声明与使用 #include<iostream.h> void Swap(int& a,int& b); int main( ) { int x(5), y(10); cout<<"x="<<x<<" y="<<y<<endl; Swap(x,y); //Swap(&x,&y); return 0; } 交换函数以引用为参数,达到了交换目的。

void Swap(int& a, int& b) int t; t=a; a=b; b=t; } 运行结果: x=5 y=10 x=10 y=5

例3-13 引用调用举例 函数的声明与使用 #include <iostream.h> #include <iomanip.h> void fiddle(int in1, int &in2); int main( ) { int count = 7, index = 12; cout << "The values are "; cout<<setw(5)<<count; cout<<setw(5)<<index<<endl; fiddle(count, index); return 0; }

void fiddle(int in1, int &in2) { in1 = in1 + 100; in2 = in2 + 100; cout << "The values are "; cout<<setw(5)<<in1; cout<<setw(5)<<in2<<endl; } 运行结果: The values are 7 12 The values are 107 112 The values are 7 112 void fiddle(int in1, int &in2) 第二个参数是引用,因此在子函数中改变了主函数的变量 index 。

引用 引用不是值,不占存储空间,声明引用时,目标的存储状态不会改变。 引用运算符与地址操作符使用相同的符号。但它们是不一样的。 引用运算符只在声明的时候使用,它放在类型名后面。例: int& rint=intone; 任何其他“&”的使用都是地址操作符。 例 int *ip=&intone; cout<<&ip; 引用一旦初始化,它就维系在一定的目标上,再也不分开。任何对该引用的赋值都是对引用所维系的目标赋值,而不是将引用维系到另一个目标上。见例子引用.cpp

#include<iostream.h> void main() { int intOne; int & rInt=intOne; intOne=5; cout<<"intOne:"<<intOne<<endl; cout<<"rInt:"<<rInt<<endl; cout<<"&intOne:"<<&intOne<<endl; cout<<"&rInt:"<<&rInt<<endl;

int intTwo=8; rInt=intTwo; cout<<"intOne:"<<intOne<<endl; cout<<"intTwo:"<<intTwo<<endl; cout<<"rInt:"<<rInt<<endl; cout<<"&intOne:"<<&intOne<<endl; cout<<"&intTwo:"<<&intTwo<<endl; cout<<"&rInt:"<<&rInt<<endl; }

运行结果: intOne:5 rInt:5 &intOne:0110F150 &rInt:0110F150 intOne:8 intTwo:8 rInt:8 &intOne:0110F150 &intTwo:0110F14E &rInt:0110F150 intOne:5 rInt:5 &intOne:0110F150 &rInt:0110F150

引用 引用调用:用引用作为形参的函数调用。 将引用作为形参,用实参来初始化形参,成为实参的一个别名,对形参的任何操作也就会直接作用于实参。 引用与指针有很大差别: 指针是个变量,可以把它再赋值成指向别处的地址。 建立引用时必须进行初始化,决不会再将其关联到其它不同的变量。 引用调用:用引用作为形参的函数调用。 将引用作为形参,用实参来初始化形参,成为实参的一个别名,对形参的任何操作也就会直接作用于实参。 引用传递的内存布局与指针相仿,只是操作完全不同。

内联函数的需要性 内联函数(内嵌函数)解决程序的运行效率。 函数调用需要建立栈内存环境,进行参数传递,并产生程序执行转移,这些工作都需要一些时间开销。 有些函数使用频率高,但代码却很短,将其声明为内联函数。即在函数声明和定义中:inline int isnumer(char c); inline int isnumber(char c) { return (ch>=‘0’&&ch<=‘9’)?1:0; }

内联函数声明与使用 内联函数 声明时使用关键字 inline。 编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销。 注意: 内联函数体内不能有循环语句和switch语句。递归函数不能被用来做内联函数。 内联函数不能含有任何静态数据及数组声明。 内联函数的声明必须出现在内联函数第一次被调用之前。 内联函数与调用函数或内联成员函数与类定义部分必须在同一个文件中,不能放在两个文件中。 内联函数

例3-14 内联函数应用举例 内联函数 #include<iostream.h> inline double CalArea(double radius) { return 3.14*radius*radius; } int main( ) double r(3.0); double area; area=CalArea(r); cout<<area<<endl; return 0; 内联函数

内联函数 编译器看到inline后,为该函数创建一段代码,以便在后面每次碰到该函数的调用都用相应的一段代码来替换。 内联函数与宏定义 在C中,常用预处理语句#define来代替一个函数的定义。 例: #define MAX(a,b) ((a)>(b)?(a):(b)) 宏定义语句书写格式过分讲究,不会对函数参数类型进行检查。 内联函数可以得到所有宏替换效能和常规函数类型检查。

缺省形参值的作用 带缺省形参值的函数 函数在声明时可以预先给出默认的形参值,调用时如给出实参,则采用实参值,否则采用预先给出的默认形参值。 例如: void main(void) { add(10,20); //10+20 add(10); //10+6 add( ); //5+6 } int add(int x=5,int y=6) { return x+y; }

缺省形参值的说明次序 带缺省形参值的函数 缺省形参值必须从右向左顺序声明,并且在缺省形参值的右面不能有非缺省形参值的参数。因为调用时实参取代形参是从左向右的顺序。 例: 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); //错误 函数调用: add(10,8,11); add(9);

缺省形参值与函数的调用位置 带缺省形参值的函数 调用出现在函数体实现之前时,缺省形参值必须在函数原形中给出;而当调用出现在函数体实现之后时,缺省形参值需在函数实现时给出。 例: int add(int x=5,int y=6); void main(void) { add( ); //调用在实现前 } int add(int x,int y) { return x+y; } int add(int x=5,int y=6) { return x+y; } void main(void) { add( ); //调用在实现后 }

缺省形参值的作用域 带缺省形参值的函数 在相同的作用域内,缺省形参值的说明应保持唯一,但如果在不同的作用域内,允许说明不同的缺省形参。 例: int add(int x=1,int y=2); void main(void) { int add(int x=3,int y=4); add( ); //使用局部缺省形参值(实现3+4) } void fun(void) { ... add( ); //使用全局缺省形参值(实现1+2)

例3-15 带缺省形参值的函数举例 带缺省形参值的函数 #include <iostream.h> #include <iomanip.h> int get_volume(int length, int width = 2, int height = 3); int main( ) {int x = 10, y = 12, z = 15; cout << "Some box data is " ; cout << get_volume(x, y, z) << endl; cout << get_volume(x, y) << endl; cout << get_volume(x) << endl; cout << "Some box data is "; cout << get_volume(x, 7) << endl; cout << get_volume(5, 5, 5) << endl; return 0; } ①题意:给出长、宽、高,get_volum 函数计算出体积。 使用缺省形参值。 ②先执行子函数中的输出,再执行主函数中的输出。

运行结果: Some box data is 10 12 15 1800 Some box data is 10 12 3 360 int get_volume(int length, int width, int height) { cout<<setw(5)<<length <<setw(5)<<width<<setw(5)<<height<<' '; return length * width * height; } 运行结果: Some box data is 10 12 15 1800 Some box data is 10 12 3 360 Some box data is 10 2 3 60 Some box data is 10 7 3 210 Some box data is 5 5 5 125

函数重载的需要性 在C中,要完成两个变量相加,根据变量类型不同,规定不同的函数名。 int iadd(int,int); long ladd(long,long); double dadd(double,double);char cadd(char,char); 用C处理,需给四个函数规定四个不同的函数名,程序员需记住四件事。 在C++中,引入重载,只需给这四个函数起一个共同的名字add,它们的参数类型不同,当调用函数时,编译器根据实参类型来确定到底调用哪个重载函数,程序员只需记住add一件事,其余的则都是系统的事。

重载函数的声明 函 数 重 载 C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。 函 数 重 载 C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载。方便使用,便于记忆。 函数重载:两个以上的函数,取相同的函数名,但形参的个数或类型不同,编译器根据实参和形参的类型及个数的最佳匹配,自动确定调用哪一个函数。其中的每个函数称为重载函数。 例: 形参类型不同 int add(int x, int y); float add(float x, float y); 形参个数不同 int add(int x, int y); int add(int x, int y, int z);

注意事项 函 数 重 载 重载函数的形参必须不同: 个数不同或类型不同。 函 数 重 载 重载函数的形参必须不同: 个数不同或类型不同。 编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。 int add(int x,int y); int add(int a,int b); 编译器不以形参名来区分 int add(int x,int y); void add(int x,int y); 编译器不以返回值来区分 不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。这样不好: int add(int x,int y) { return x+y; } float add(float x,float y) { return x-y; }

例3-16 重载函数应用举例 编写三个名为add的重载函数,分别实现两整数相加、两实数相加和两个复数相加的功能。 #include<iostream.h> struct complex { double real; double imaginary; };

void main(void) { int m, n; double x, y; complex c1, c2, c3; int add(int m, int n); double add(double x, double y); complex add(complex c1, complex c2); cout<<"Enter two integer: "; cin>>m>>n; cout<<"integer "<<m<<'+'<<n<<"="<<add(m,n)<<endl;

cout<<"Enter two real number: "; cin>>x>>y; cout<<"real number "<<x<<'+'<<y<<"= "<<add(x,y) <<endl; cout<<"Enter the first complex number: "; cin>>c1.real>>c1.imaginary; cout<<"Enter the second complex number: "; cin>>c2.real>>c2.imaginary; c3=add(c1,c2); cout<<"complex number (" <<c1.real<< ',' << c1.imaginary <<")+("<<c2.real<<',' <<c2.imaginary<<")=("<<c3.real<<',' <<c3.imaginary<<")\n"; }

int add(int m, int n) { return m+n; } double add(double x, double y) { return x+y; } complex add(complex c1, complex c2) { complex c; c.real=c1.real+c2.real; c.imaginary=c1.imaginary+c2.imaginary; return c; }

运行结果: Enter two integer: 3 5 integer 3+5=8 Enter two real number: 2.3 5.8 real number 2.3+5.8= 8.1 Enter the first complex number: 12.3 45.6 Enter the second complex number: 56.7 67.8 complex number (12.3,45.6)+(56.7,67.8)= (69,113.4)

函数模板 重载函数,只是使用相同的函数名,每个函数的函数体仍要分别定义。 例 两个求绝对值的重载函数: 这两个函数只有参数类型不同,功能完全一样。若能写一段通用代码适用于多种不同数据类型,可提高代码重用性。通过函数模板可将多个重载函数归为一个。 int abs(int x) { return x<0?-x:x;} double abs(double x) { return x<0?-x:x;}

函数模板的声明 函 数 模 板 函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计。 声明方法: 函 数 模 板 函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计。 声明方法: template <typename 模板参数表> 函数定义 或 template<class 模板参数表> 函数定义

例3-17 求绝对值函数的模板 函 数 模 板 #include<iostream.h> 函 数 模 板 #include<iostream.h> template<typename T> T abs(T x) { return x<0?-x:x; } void main( ) { int n=-5; double d=-5.5; cout<<abs(n)<<endl; cout<<abs(d)<<endl; }

运行结果: 5 5.5 分析 编译器从调用abs( )时实参的类型,推导出函数模板的类型参数。例如,对于调用表达式abs(n),由于实参n为int型,所以推导出模板中类型参数T为int。 当类型参数的含义确定后,编译器将以函数模板为样板,生成一个函数: int abs(int x) { return x<0?-x:x; }

函数模板 函数模板定义不是一个实实在在的函数,编译系统不为其产生任何执行代码,该定义只是对函数的描述,表示它每次能单独处理在类型形式参数表中说明的数据类型。 当编译系统发现有一个函数调用:funcname(实参表);将根据实参表中的类型,确认是否匹配函数模板中对应的形式参数表,然后生成一个重载函数(模板函数)

#include<iostream.h> #include<string.h> template<class T> //template<typename T> T max(T a, T b) { return a>b?a:b; } char* max(char* a, char* b) { return (strcmp(a,b)>0?a:b); } 其名字与函数模板的名字相同,但操作不同,函数体中采用了字串比较函数,需用重载的方法把它们区分开,这就是重载模板函数。编译器首先匹配重载函数,然后再寻求模板的匹配。

void main() {cout<<"Max(3,5) is "<<max(3,5)<<endl; cout<<"Max('3','5') is "<<max('3','5')<<endl; cout<<"Max(\"Hello\",\"Gold\") is " <<max("Hello","Gold")<<endl; } 运行结果: Max(3,5) is 5 Max('3','5') is 5 Max("Hello","Gold") is Hello

函数模板与函数重载 函数模板适用于函数名相同,算法相同,参数个数相同,但类型不同的问题。 函数重载适用于函数名相同,算法相同,参数个数或类型不同的问题。 例:int f(int x,int y) int f(int x,int y) {return x+y;} {return x*y;} 这两个函数不是重载函数。

C++系统函数 使用C++系统函数 C++的系统库中提供了几百个函数可供程序员使用。 使用系统函数时要包含相应的头文件。 例如:求平方根函数(sprt)、求绝对值函数(abs)等。 使用系统函数时要包含相应的头文件。 例如:math.h

例3-18 系统函数应用举例 使用C++系统函数 题目: 分析: 从键盘输入一个角度值,求出该角度的正弦值、余弦值和正切值。 系统函数中提供了求正弦值、余弦值和正切值的函数:sin( )、cos( )、tan( ),函数的说明在头文件math.h中。

#include<iostream.h> #include<math.h> const double pi(3.14159265); void main( ) { double a,b; cin>>a; b=a*pi/180; cout<<"sin("<<a<<")="<<sin(b)<<endl; cout<<"cos("<<a<<")="<<cos(b)<<endl; cout<<"tan("<<a<<")="<<tan(b)<<endl; }

运行结果: 30 sin(30)=0.5 cos(30)=0.866025 tan(30)=0.57735

查找系统函数的使用说明 使用C++系统函数 查编译系统的库函数手册 查联机帮助——VC++6.0联机帮助的使用方法: help/Contents ->(“活动子集”栏)Visual C++ Documentation -> Visual C++ Documentation ->Using Visual C++ -> Visual C++ Programmer's Guide -> Run-Time Library Reference ->Run Time Routines by Category -> Run Time Routines by Category

作 业 复习第三章,预习第四章 3-2, 3-13, 3-15 学习使用联机帮助系统查找系统函数