收藏 分销(赏)

第三章函数.pptx

上传人:可**** 文档编号:14578689 上传时间:2026-10-15 格式:PPTX 页数:103 大小:829.97KB 下载积分:8 金币
下载 相关
第三章函数.pptx_第1页
第1页 / 共103页
第三章函数.pptx_第2页
第2页 / 共103页


点击查看更多>>
资源描述
Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,C+,程序设计,*,Click to edit Master title style,第,3,章 函数,C+,程序设计,第1页,第1页,本小节内容,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,函数重载,3.6,函数模板,C+,程序设计,第2页,第2页,3.1,函数定义,在编辑一个大型程序时,即使各个函数前后次序不同,程序执行开始点永远是主函数。主函数按照调用与被调用关系调用子函数。子函数假如与其它子函数又存在调用与被调用关系,当然还能够再调用其它子函数。,C+,程序设计,第3页,第3页,3.1,函数定义,函数是面向对象程序设计中基本抽象单元,是对功效抽象。,C+,程序设计,第4页,第4页,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,函数重载,3.6,函数模板,3.7,变量作用域,C+,程序设计,第5页,第5页,3.1,函数定义,主函数,main(),调用函数,func1,调用函数,func2,函数,func2,(),函数,func1(),函数,func2(),C+,程序设计,第6页,第6页,在一对调用与被调用关系中,我们把调用其它函数函数称为主调函数,被其它函数调用函数称为被调函数。在一个较为复杂大型程序中,一个函数很可能同时饰演两种不同角色主调函数与被调函数,即既调用别函数(被调函数)又被另外函数(主调函数)调用。函数普通应恪守先定义后调用标准,不然应在调用函数中先进行原形说明。,C+,程序设计,第7页,第7页,一、函数定义,一个完整函数定义由两部分构成,即,函数头与函数体。,1.,函数定义普通语法形式,(,形式参数表,),阐明性语句序列;,实现函数功效语句系列;,函数头,函数体,C+,程序设计,第8页,第8页,函数头是指上述格式中,(形式参数表)。其中,函数名,可由函数设计者命名,能够是任何一个不重复合法标识符(,唯一例外是,主函数必须命名为,main,)。,函数体是指上述格式中被一对大括号括起复合语句部分。该函数所应,实现功效由相应复合语句完毕。,C+,程序设计,第9页,第9页,2,、形式参数表,name,1,name,2,.,name,n,3,、函数返回值,由,return,语句给出,比如:,return 0,无返回值函数(,void,类型),不必写,return,语句。,C+,程序设计,第10页,第10页,函数在没有被调用时候其形参只是一个符号,它标志着在形参出现位置应当有一个什么类型数据。函数在被调用时才由主调函数将实际参数,(,简称实参,),赋予形参,。从这一点上说,,C+,中函数与数学中函数概念极其相同。比如,我们都熟悉下列数学中函数形式:,f(x)=3x+5x-2,这个函数只有当自变量,x,被赋以拟定值以后,才干计算出函数值。,C+,程序设计,第11页,第11页,二、函数调用,假如没有遵守先定义后调用原则,调用函数之前先要在主调函数中申明函数原型。在主调函数中,或所有函数之前,按下列形式进行,函数原型申明:,(,含类型阐明形参表,),;,函数原型申明,C+,程序设计,第12页,第12页,假如是在所有函数之前申明了函数原型,那么该函数原型在本程序文献中任何地方都有效,,也就是说,在本程序文献中任何地方都能够依照该原型调用相应函数。假如是在某个主调函数内部申明了被调函数原型,那么该原型就只能在这个函数内部有效。,申明了函数原型之后,便能够按下列形式调用子函数:,(,实参,1,,实参,2,,,,实参,n),调用函数,C+,程序设计,第13页,第13页,实参列表中应给出与函数原型中形参个数相同、类型相符实参,每个实参都能够是常量、变量或表示式三者之一。实参与实参之间用逗号作为分隔符。注意,这里逗号不是顺序求值运算符。函数调用能够作为一条语句,这时函数能够没有返回值。函数调用也能够出现在表示式中,这时就必须有一个明确返回值。函数调用示比如下。,C+,程序设计,第14页,第14页,【,例,1】,编写一个,n,!函数,并调用。,(,1,),n,!函数,long fac(int n),int i,jc=1;,if(n0),coutn,不能小于,0endl;,return-1;,for(i=1;i=n;i+),jc*=i;,return jc;,C+,程序设计,第15页,第15页,(,2,)函数调用,#include,long fac(int n);/,原型阐明语句,void main(),int a;,cout,请输入,a,值:,a;,couta,!,=fac(a)endl;,C+,程序设计,第16页,第16页,【,例,2】,求任意两个数最大值函数及其调用。,#include,int max(int x,int y);,void main(),int a,b,c;,cout,请输入,a,、,b,、,c,值:,abc;,cout“a,、,b,、,c,最大值是,max(max(a,b),c)endl;,int max(int x,int y),if(xy)return y;,else return x;,C+,程序设计,第17页,第17页,【,例,3】,编写一个函数,把华氏温度转换为摄氏温度,公式为,C=(F-32)*5/9,,公式中,F,代表华氏温度,,C,代表摄氏温度。在主函数中提醒用户输入一个华氏温度,并完毕输入及输出,由函数完毕转化功效。,程序代码下列:,#include,float hstoss(float fHuashi);/,原型阐明,void main(),C+,程序设计,第18页,第18页,float fHuashi;,coutendlfHuashi;,cout,华氏,fHuashi,度相应摄氏温度,hstoss(fHuashi),度,endl;,/,函数调用作为一个表示式出现在输出语句中,float hstoss(float fHuashi),float fSheshi;,fSheshi=(fHuashi-32)*5/9;,C+,程序设计,第19页,第19页,return(fSheshi);,程序运营结果为,输入一个华氏温度值:,68,华氏,68,度相应摄氏,20,度,C+,程序设计,第20页,第20页,函数参数用于在调用函数与被调用函数之间进行数据传递。,在函数定义时,函数名后面括号内参数称为形式参数,(,简称,形参,),。在函数被调用时,函数名后面括号内参数称为实际参数,(,简称,实参,),。,三、函数参数传递,C+,程序设计,第21页,第21页,当函数未被调用时,,C+,编译系统并没有给函数形参分派相应内存空间,函数,形参,更不会有实际值。,只有在,函数被调用,时,,C+,编译系统这时才为形参分派实际存储单元,并将实参与形参结合。,实参能够是常量、变量或表示式,其类型必须与形参相符。,函数参数传递,,指就是,形参与实参结合,(,简称形实结合,),过程。,形实结合方式有值调用和引用调用两种。,三、函数参数传递,C+,程序设计,第22页,第22页,值调用是指当发生函数调用时,编译系统为形参分派对应存放空间而且直接将实参值复制给形参,这么形参和实参就各自拥有不同存放单元,且形参是实参副本。因此,值调用过程是参数值单向传递过程,一旦形参取得了与实参相同值就与实参脱离关系,以后不论形参发生多大改变,都决不会反过来影响到实参。,1.,值调用,C+,程序设计,第23页,第23页,【,例,4】,从键盘输入两个整数,互换位置后输出(互换未成功)。,#include,void swap(int a,int b);,void main(),int x,y;,x=5;,y=10;,1.,值调用,C+,程序设计,第24页,第24页,coutx=x y=yendl;,swap(x,y);/,互换,x,y,值,coutafter swapendl;,coutx=x y=yendl;,void swap(int a,int b),int t;,t=a;,a=b;,b=t;,1.,值调用,C+,程序设计,第25页,第25页,程序运营结果为,x=5 y=10,after swap,x=5 y=10,分析:从上面程序运营结果能够看出,并没有达到互换目的。这是由于采用传递方式不合乎问题要求。在单向值传递方式中,形参值虽确实进行了互换,但这些改变对实参不起任何作用。,1.,值调用,C+,程序设计,第26页,第26页,执行主调函数中函数调用语句,swap(x,、,y),后,编译系统将实参,x,中值,5,传递给虚参,a,,将实参,y,中值,10,传递给虚参,b,;在,swap,函数中,,a,、,b,中值完毕互换;返回主函数时,实参,x,、,y,中值不受虚参,a,、,b,影响,并未进行互换。,1.,值调用,C+,程序设计,第27页,第27页,显而易见,值调用时参数传递方式是实参单向复制其值给虚参,假如我们想使子函数中对形参所做任何更改也能及时反应给主函数中实参(即希望形参与实参影响是互相或称是双向),又该怎么办呢?这就需要改变调用方式,即采用第二种参数传递方式,引用调用,。,引用是一个特殊类型变量,能够被认为是某一个变量别名,。通过引用名与通过被引用变量名访问变量效果是同样。这就是说,对形参任何操作也就直接作用于实参。,2.,引用调用,C+,程序设计,第28页,第28页,比如:,int a,b;,int,/,建立一个,int,型引用,ra,,并将其初始化为变量,a,一个别名,b=10;,ra=b;/,相称于,a=b;,注意:,申明一个引用时,必须同时对它进行初始化,使它与一个已存在对象关联。,2.,引用调用,C+,程序设计,第29页,第29页,一旦一个引用被初始化后,就不能改变关联对象。换言之,一个引用从它被申明之后,就必须确定是哪个变量别名,而且自始至终只能作为这一个变量别名,不能另作他用。,形参也能够引用方式出现在形参表中。引用作为形参情况与变量引用稍有不同。这是因为,形参初始化不在类型说明时进行,而是在执行主调函数中调用语句时,才为形参分派内存空间,同时用实参来初始化形参。,2.,引用调用,C+,程序设计,第30页,第30页,【,例,5】,使用引用调用改写例,7-5,程序,,使两实参中数真正进行互换。,#include,void swap(int,void main(),int x,y;,x=5;,y=10;,coutx=x y=yendl;,2.,引用调用,C+,程序设计,第31页,第31页,swap(x,y);/,互换,x,y,值,coutafter swapendl;,coutx=x y=yendl;,void swap(int&a,int&b),int t;,t=a;,a=b;,b=t;,2.,引用调用,C+,程序设计,第32页,第32页,程序运营结果为,x=5 y=10,after swap,x=10 y=5,分析:子函数,swap,两个参数都是引用,当被调用时,它们分别被初始化成为,a,和,b,别名。因此,在子函数,swap,中将两个参数值进行互换后,互换结果能够返回主函数,main,。,2.,引用调用,C+,程序设计,第33页,第33页,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,函数重载,3.6,函数模板,3.7,变量作用域,C+,程序设计,第34页,第34页,3.2,函数调用机制,一个,C+,源程序,通过编译以后形成与,源程序主名相同但后缀为,.exe,可执行文献,,且存储在外存储器中。当该,.exe,可执行程序被运营时,首先从外存将程序代码装载到内存代码区,然后从,main,函数起始处开始执行,。程序在执行过程中,假如碰到了对其它函数调用,则暂停当前函数执行,,C+,程序设计,第35页,第35页,保留下一条指令地址,(,即返回地址,作为从子函数返回后继续执行,入口点,),,,并,保留现场,(,主要是一些存储器内容,),,,然后转到,子函数入口地址,,,执行子函数,。,当,碰到,return,语句或者子函数结束时,,,则,恢复先前保留现场,,,并从先前保留返回地址开始继续执行。图,2,阐明了函数调用和返回过程,图中标号标明了执行顺序。,3.2,函数调用机制,C+,程序设计,第36页,第36页,图,2,函数调用和返回示意图,Main(),func(),调用,func(),结束,返回,保留:,返回地址,当前现场,恢复:,主调函数现场,返回地址,3.2,函数调用机制,C+,程序设计,第37页,第37页,作业,1,:设,N=10,,,X=2,、,4,、,6,、,8,,即求,N,事件中每次取,2,、,4,、,6,、,8,组合数。,分析:这个问题需要重复利用两个公式:,N!,N!/X!/(N-X)!,设计两个函数:一个求整数阶乘函数,lJiecheng,和一个求组合数函数,lComb,。由主函数,main,调用,lComb,,,lComb,又调用,lJiecheng,。,C+,程序设计,第38页,第38页,程序代码下列:,#include,long lJiecheng(int n),long rt=1;,int i;,for(i=1;i=n;i+),rt=rt*i;,return rt;,C+,程序设计,第39页,第39页,long lComb(int N,int X),return lJiecheng(N)/lJiecheng(X)/lJiecheng(N-X);,void main(),long lJiecheng(int n);,long lComb(int N,int X);,C+,程序设计,第40页,第40页,int iNum,x;,do,coutiNum;,while(iNum10);,for(x=2;x10;x+=2)coutC(iNum,x)=lComb(iNum,x)0),1 (n=0),这是一个递归形式公式,应当用递归函数实现,.,3.3,递 归 函 数,C+,程序设计,第46页,第46页,源程序,:,#include,Long,fac,(int n),long,f,;,if(n0),cour“n0,data error!”endl;,else if(n=0)f=1;,else,f,=,fac(n-1),*n;,return,f,;,3.3,递 归 函 数,C+,程序设计,第47页,第47页,void main(),long fac(int n);,int n;,long y;,coutn;,y=fac(n);,coutn!=yendl;,运营结果:,Enter a positive integer:8,8!=40320,3.3,递 归 函 数,C+,程序设计,第48页,第48页,循环终止条件,一个递归调用语句(递推关系),递归条件,3.3,递 归 函 数,C+,程序设计,第49页,第49页,作业,2,:有,5,个人坐在一起,问第,1,个人多少岁,他说比第,2,个人大,2,岁。问第,2,个人多少岁,他说比第,3,个人大,2,岁。问第,3,个人多少岁,他说比第,4,个人大,2,岁。问第,4,个人多少岁,他说比第,5,个人大,2,岁。最后问第,5,个人,他说是,12,岁。请问第,1,个人多少岁?,分析:这是一个递归问题。每一个人年龄都比其后那个人年龄大,2,,即,3.3,递 归 函 数,C+,程序设计,第50页,第50页,age(1)=age(2)+2,age(2)=age(3)+2,age(3)=age(4)+2,age(4)=age(5)+2,age(5)=12,能够用公式表示下列:,12(n=5),age(n)=,age(n+1)+2(n5),3.3,递 归 函 数,C+,程序设计,第51页,第51页,程序代码下列:,#include,int age(int n),int ss;,if(n=5)ss=12;,elsess=age(n+1)+2;,return(ss);,void main(),3.3,递 归 函 数,C+,程序设计,第52页,第52页,int age(int n);,cout,第一个人年龄为,age(1),岁,endl;,程序运营结果为,第一个人年龄为,20,岁,3.3,递 归 函 数,C+,程序设计,第53页,第53页,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,函数重载,3.6,函数模板,3.7,变量作用域,C+,程序设计,第54页,第54页,3.4,默认参数函数,在函数定义中通过赋值运算就可指定默认参数值。一旦程序在调用该函数时,假如给出,实参,,则用,实参初始化形参,;假如,没有给出实参,,则,C+,编译系统,自动以预先赋值默认参数值作为传入数值,。普通情况下都将调用该函数时经惯用到常数作为默认参数值,这样在调用时就无需每次都写出该值了。指定默认参数值能够使函数使用更为简朴,同时也增强了函数可重用性。,C+,程序设计,第55页,第55页,【,例,7】,带默认形参值函数例题。,#include,int mult(int n,int,k=2,)/,第二个形参含有默认值,if(k=2),return(n*n);,else,return(,mult(n,k-1)*n);,void main(),3.4,默认参数函数,C+,程序设计,第56页,第56页,coutendl,mult(5),endl;,/*,形参,n,用实参来初始化为,5,,,形参,k,采用默认值,2,,实现,5*5*/,cout,mult(5,3),endl;,/*,用实参来初始化形参,,n,为,5,,,k,为,3,,实现,5*5*5*/,程序运营结果为,25,125,3.4,默认参数函数,C+,程序设计,第57页,第57页,默认形参值必须按,从右向左,顺序定义。,在有默认值形参右面,不能出现无默认值形参,。由于在调用时,实参初始化形参是按从左向右顺序。比如:,void try(int j=3,int k),void try(int j,int k=2,int m),void try(int j,int k=7),void try(int j,int k=2,int m=3),void try(int j=3,int k=2,int m=3),/,非法,/,非法,/,合法,/,合法,/,合法,3.4,默认参数函数,C+,程序设计,第58页,第58页,默认形参值应当在函数原型中给出。,比如:,int multi(int x=2,int y=5),;,/,默认形参值在函数原型中给出,void main(),multi(),;,/,并非无参调用,而是采用默认值,,x,取值,2,,,y,取值,5,int multi(int x,int y),return(x*y),;,3.4,默认参数函数,C+,程序设计,第59页,第59页,在相同作用域内,默认形参值说明应保持唯一。但假如在不同作用域内,允许说明不同默认形参。这里作用域是指直接包含着函数原型说明大括号所界定范围。比如:,int add(int x=2,int y=5);/全局默认形参值,void main(),int add(int x=1,int y=9);/局部默认形参值,3.4,默认参数函数,C+,程序设计,第60页,第60页,add(),;,/,此处调用时,采用局部默认形参值,,x,取值,1,,,y,取值,9,void func(void),add()/,此处调用时,采用全局默认形参值,,x,取值,2,,,y,取值,5,3.4,默认参数函数,C+,程序设计,第61页,第61页,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,内联函数,3.6,函数模板,3.7,变量作用域,C+,程序设计,第62页,第62页,3.5,内 联 函 数,内联函数,(,也称,在线函数,),是在,C+,中为,提升程序运营效率而引入,。所有函数,调用时都会产生一些额外开销,主要是系统栈保护、代码传递、系统栈恢复以及参数传递等。,对于一些,函数体很小,但又,经常使用函数,,由于被,调用频率非常高,,这种额外开销也就很可观,有时甚至会对运营效率产生本质影响。,C+,程序设计,第63页,第63页,使用,内联函数,正是处理这一问题手段。,内联函数,不是在调用时发生转移,,,而是,在编译时将函数体嵌入在每一个调用语句处。,这样就相对,节约了参数传递、系统栈保护与恢复等开销。,内联函数在定义时使用,关键字,inline,区别于普通函数,其语法形式下列:,(,含类型阐明形参表,),函数体,3.5,内 联 函 数,C+,程序设计,第64页,第64页,比如:,inline int mul(int a,int b),return a*b,;,当程序中出现,mul(2+3,,,4),函数调用时,编译程序就会将其扩展为,(2+3)*4,。关键字,inline,是一个编译命令,编译程序在碰到这个命令时将统计下来,在处理内联函数调用时,编译程序就试图产生扩展码。这样从使用者角度来看,内联函数在语法上与普通函数没有什么区别,只是在编译程序生成目的代码时才区别处理。,3.5,内 联 函 数,C+,程序设计,第65页,第65页,注意:,内联函数体内普通不能有循环语句和,switch,语句。,内联函数定义必须出现在第一次被调用之前。,假如违反了上述注意事项中任一项,编译程序就会无视关键字,inline,存在,像处理普通函数同样处理,不生成扩展代码。因此,,只有很简朴而使用频率很高函数才被阐明为内联函数,。内联函数会扩大目的代码,使用时要谨慎。,3.5,内 联 函 数,C+,程序设计,第66页,第66页,【,例,8】,内联函数例题。,#include,#include,inline int max(int a,int b),if(ab),return a;,else,return b;,3.5,内 联 函 数,C+,程序设计,第67页,第67页,void main(),int a,b,c,d;,a=210;,b=150;,c=20;,d=max(a,b);,d=max(d,c);/,编译时两个调用处均被,替换为,max,函数体语句。,3.5,内 联 函 数,C+,程序设计,第68页,第68页,coutThe biggest of,setw(5)a,setw(5)b,setw(5)c is dendl;,程序运营结果为,The biggest of 210 150 20 is 210,3.5,内 联 函 数,C+,程序设计,第69页,第69页,回顾,C+,程序设计,第70页,第70页,默认形参值必须按,从右向左,顺序定义。,在有默认值形参右面,不能出现无默认值形参,。由于在调用时,实参初始化形参是按从左向右顺序。比如:,void try(int j=3,int k),void try(int j,int k=2,int m),void try(int j,int k=7),void try(int j,int k=2,int m=3),void try(int j=3,int k=2,int m=3),/,非法,/,非法,/,合法,/,合法,/,合法,3.4,默认参数函数,C+,程序设计,第71页,第71页,使用,内联函数,正是处理这一问题手段。,内联函数,不是在调用时发生转移,,,而是,在编译时将函数体嵌入在每一个调用语句处。,这样就相对,节约了参数传递、系统栈保护与恢复等开销。,内联函数在定义时使用,关键字,inline,区别于普通函数,其语法形式下列:,(,含类型阐明形参表,),函数体,3.5,内 联 函 数,C+,程序设计,第72页,第72页,注意:,内联函数体内普通不能有循环语句和,switch,语句。,内联函数定义必须出现在第一次被调用之前。,对内联函数不能进行异常接口申明。,假如违反了上述注意事项中任一项,编译程序就会无视关键字,inline,存在,像处理普通函数同样处理,不生成扩展代码。因此,,只有很简朴而使用频率很高函数才被阐明为内联函数,。内联函数会扩大目的代码,使用时要谨慎。,3.5,内 联 函 数,C+,程序设计,第73页,第73页,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,内联函数,3.6,函数重载,3.7,函数模板,3.8,变量作用域,C+,程序设计,第74页,第74页,【,例,7-9】,#include,int add(int x,int y),return(x+y);,double add(double x,double y),return(x+y);,3.6,函 数 重 载,C+,程序设计,第75页,第75页,int add(int x,int y,int z),return(x+y+z);,void main(),int a,b,c;,a=add(5,10);,b=add(5.7,10.3);,c=add(5,10,20);,couta=ab=bendl;,程序运营结果为,a=15 b=16.0 c=35,3.6,函 数 重 载,C+,程序设计,第76页,第76页,3.6,函 数 重 载,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,);,C+,程序设计,第77页,第77页,3.6,函 数 重 载,int add(int x,int y);,int add(int a,int b);,编译器不以形参名来区别,int add(int x,int y);,void add(int x,int y);,编译器不以返回值来区别,重载函数形参必须不同:个数不同或类型不同。,编译程序将依据实参和形参类型及个数最正确匹配来选择调用哪一个函数。,注意:,C+,程序设计,第78页,第78页,3.6,函 数 重 载,不要将不同功效函数申明为重载函数,以免出现调用结果误解、混同。这么不好:,int add(int x,int y),return x,+,y;,float add(float x,float y),return,x,-,y,;,注意:,C+,程序设计,第79页,第79页,3.6,函 数 重 载,例子,例,9,:编写三个名为,add,重载函数,分别实现两整数相加、两浮点数相加和三个整数相加功效。,C+,程序设计,第80页,第80页,【,例,9】,#include,int add(int x,int y),return(x+y);,double add(double x,double y),return(x+y);,3.6,函 数 重 载,C+,程序设计,第81页,第81页,int add(int x,int y,int z),return(x+y+z);,void main(),int a,b,c;,a=add(5,10);,b=add(5.7,10.3);,c=add(5,10,20);,couta=ab=bendl;,程序运营结果为,a=15 b=16.0 c=35,3.6,函 数 重 载,C+,程序设计,第82页,第82页,3.1,函数定义与使用,3.2,函数调用机制,3.3,递归函数,3.4,默认参数函数,3.5,内联函数,3.6,函数重载,3.7,函数模板,3.8,变量作用域,C+,程序设计,第83页,第83页,3.7,函 数 模 板,有诸多时候,我们希望所设计算法能够处理各种数据类型。但是,即使这一算法被设计为重载函数,也只是使用相同函数名,函数体仍然要分别定义。,下列面两个求较小值函数:,C+,程序设计,第84页,第84页,例7-10,int small(int x,int y),return xy?x:y;,double small(double x,double y),return xy?x:y;,考察以上两个函数,有什么特点?,只有参数类型不同,返回值类型不同,功效则完全一样。类似这么情况,能够使用函数模板,从而避免函数体重复定义。,3.7,函 数 模 板,C+,程序设计,第85页,第85页,函数模板能够用来创建一个通用功效函数,以支持各种不同形参,简化重载函数函数体设计。它最大特点是把函数所使用数据类型作为参数。,函数模板定义形式以下:,函数定义,3.7,函 数 模 板,C+,程序设计,第86页,第86页,#include,template,T,small(,T,x,T,y,),return xy?x:y,;,void main(),3.7,函 数 模 板,C+,程序设计,第87页,第87页,int m=1,n=8;,double u=5.5,v=99.3;,small(m,n);/,整型,small(u,v);,3.7,函 数 模 板,C+,程序设计,第88页,第88页,int,small(,int,x,int,y,),return xy?x:y,;,small(m,n);/m,n,是,int,型,3.7,函 数 模 板,C+,程序设计,第89页,第89页,float,small(,float,x,float,y,),return xy?x:y,;,small(u,v);/m,n,是,float,型,3.7,函 数 模 板,C+,程序设计,第90页,第90页,【,例,7-11】,定义一个能互换两个变量值函数,要求用模板函数实现。,#include,template,void swap(,T,&x,T,&y,),T z;,z=y;y=x;x=z;,void main(),3.7,函 数 模 板,C+,程序设计,第91页,第91页,int m=1,n=8;,double u=-5.5,v=99.3;,coutm=m n=nendl;,coutu=u v=vendl;,swap(m,n);/,整型,swap(u,v);/,双精度型,coutm,与,n,,,u,与,v,互换以后:,endl;,coutm=m n=nendl;,coutu=u v=vendl;,3.7,函 数 模 板,C+,程序设计,第92页,第92页,程序运营结果为,:,m=1 n=8,u=-5.5 v=99.3,m,与,n,,,u,与,v,互换以后:,m=8 n=1,u=99.3 v=-5.5,分析:编译系统从调用,swap(),时,依据实参类型推导出函数模板类型参数。,3.7,函 数 模 板,C+,程序设计,第93页,第93页,于调用,swap(m,,,n),,,由于实参,m,及,n,为,int,类型,,因此,推导出模板中类型参数,T,为,int,。,当类型参数含义拟定后,编译器将以函数模板为样板生成一个函数:,int swap(int&x,int&y),int z,;,z=y,;,y=x,;,x=z,;,同样,对于调用,swap(u,,,v),,由于实参,u,、,v,为,double,类型,因此,,推导出模板中类型参数,T,为,double,。,3.7,函 数 模 板,C+,程序设计,第94页,第94页,接着,编译器将以函数模板为样板,生成下列函数:,double swap(double&x,double&y),double z,;,z=y,;,y=x,;,x=z,;,3.7,函 数 模 板,C+,程序设计,第95页,第95页,因此,当主函数第一次调用,swap(),时,执行事实上是由函数模板生成函数,:,int swap,(,int&x,int&y,),当主函数第二次调用,swap(),时,执行事实上是由函数模板生成函数,:,double swap,(,double&x,double&y,),3.7,函 数 模 板,C+,程序设计,第96页,第96页,例,7-12,将下列函数用函数模版实现,int add(int x,int y),return(x+y);,double add(double x,double y),return(x+y);,3.7,函 数 模 板,C+,程序设计,第97页,第97页,#include,template,T add(T x,T y),return(x+y);,void main(),int a,b;,a=add(5,10);,b=add(5.7,10.3);,couta=ab=bendl;,3.7,函 数 模 板,C+,程序设计,第98页,第98页,作业,1,、编写三个重载函数,分别求两个整数、两个双精度型数、两个单精度数中最大数。,2,、将上题用模板实现。,C+,程序设计,第99页,第99页,C+,程序设计,第100页,第100页,3.6,函 数 重 载,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,);,C+,程序设计,第101页,第101页,3.6,函 数 重 载,int add(int x,int y);,int add(int a,int b);,编译器不以形参名来区别,int add(int x,int y);,void add(int x,int y);,编译器不以返回值来区别,重载函数形参必须不同:个数不同或类型不同。,编译程序将依据实参和形参类型及个数最正确匹配来选择调用哪一个函数。,注意:,C+,程序设计,第102页,第102页,函数模板能够用来创建一个通用功效函数,以支持各种不同形参,简化重载函数函数体设计。它最大特点是把函数所使用数据类型作为参数。,函数模板定义形式以下:,函数定义,3.7,函 数 模 板,C+,程序设计,第103页,第103页,
展开阅读全文

开通  VIP、SVIP  下载更划算
下载10份以上建议开通 VIP 会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        关注我们

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服