《函数与预处理》PPT课件.ppt
《《函数与预处理》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《函数与预处理》PPT课件.ppt(48页珍藏版)》请在三一办公上搜索。
1、第4章 函数与预处理,一.函数的概念、分类及定义,第4章 函数与预处理,函数的概念,逻辑上独立的、完成指定功能的一段代码,是编译的最小单位.有的程序设计语言分成子程序和函数两种,如 Basic,Fortran等.,由一个main函数及若干个其它函数组成.,另外,在main函数前还可以定义全局变量,声明所用函数.,C程序的结构,函数可看作为一个“黑箱”,通过参数和返回值与外界进行数据交换.,C+的程序结构,第4章 函数与预处理,一个程序中有且只能有一个main函数;函数的定义是独立的,不能嵌套定义;函数可以相互调用,但不能调用main函数;在函数被调用之前,必须先定义或声明.,关于函数的几点规定
2、,函数是模块化程序设计的基本单位,C程序就是由函数组成,因此被认为是面向函数的语言;C+采用类结构设计方式,将对象的数据及操作(函数)捆绑起来,封装于类中,如下图.,函数的分类,从用户使用的角度看,可分成两类:,标准库函数:编译系统自带的函数,用户只需在程序中包含相应的头文件,就可以调用.在连接时,系统会将相应的代码连接到用户的执行程序中.,VC+几个常用的头文件及库函数:,输入/输出库(iostream):getchar,gets,puts,scanf,printf 等;数学函数库(cmath):abs,fabs,labs,sin,cos,tan,exp 等;(cstdlib):_max,_
3、min,itoa,atoi,atol,atof,rand等;字符串处理(cstring):strlen,strcpy,strncpy,strcmp,strlwr,strupr,strchr,strrchr,strstr等;字符分类及转换(cctype):isalpha,isdigit,islower,isupper等;动态存储分配(C语言)(malloc.h):calloc,malloc,realloc,free等;时间库函数(ctime):time,ctime,_strtime等;,用户自定义函数:按C+的语法定义函数.,第4章 函数与预处理,函数的定义,定义无参函数的一般格式,第4章 函数
4、与预处理,(void)函数体;return;,注:,如果没有返回值,则为void,return 后面不需要任何返回值,甚至return 本身也可省略.函数体可以是空的,但 不能省.,例:下面的函数用于输出当前时间.,#include void PrnTime(void),char tm11;_strtime(tm);cout tm endl;,定义有参函数的一般格式,第4章 函数与预处理,(形式参数表)函数体;return;,例:求整数m,n的最大公约数.,int gcf(int m,int n)int r;while(r=m%n)!=0)m=n;n=r;return n;,内置函数,第4章
5、函数与预处理,普通函数调用时,需要花费一定的时间.对于一些频繁调用的规模较小、结构较简单的函数,C+提供了一种提高效率的方法,它将被调用的函数代码直接嵌入到调用处,这种函数称为内置函数或内联函数或内嵌函数.,inline int gcf(int m,int n);void main(void)int a,b,c;cin a b;c=gcf(a,b)cout gcf=cendl;,内置函数的概念,内置函数的定义,只要在普通函数的函数头前面加上关键字inline即可,可以加在函数定义处,也可加在声明处,或两处都加.,内置函数的例子,inline int gcf(int m,int n)int r;
6、while(r=m%n)!=0)m=n;n=r;return n;,内置函数(续),第4章 函数与预处理,说明,函数内置只是对编译系统提出的一个建议,最后由编译系统决定是否将函数内置;若内置函数中包含复杂的控制语句,如循环语句,switch语句,则作为普通函数处理.另外,如函数规模较大,也作普通函数处理.,具有函数调用的优点(如,限制局部变量的作用域),且比普通函数的执行速度更快;具有宏定义(稍后介绍)等价的效果,但不象宏定义具有副作用;,增加可执行代码的长度;当内联函数的定义作了修改,则调用内联函数的程序都要重新编译.这对于规模较大、由多个文件组成的程序,比较费时.,内置函数的好处,内置函数
7、的缺点,二.函数的声明、调用和参数传递,第4章 函数与预处理,原型方法,函数的声明,如果在函数的定义前调用该函数,则必须先声明,有两种方法:,函数声明的位置,void main()int gcf(int m,int n);int x,y,t;cin x y;t=gcf(x,y);cout t=t endl;,形式1:函数名(形参类型1,形参类型n);,形式2:函数名(形参类型1 参数名1,形参类型n 参数名n);,放在调用函数的函数体头部,函数声明的位置(续),第4章 函数与预处理,可在声明之后的整个文件中调用函数gcf.,#include head1void main(void),放在文件的
8、头部,int gcf(int m,int n);void main(void)int x,y,t;cin x y;t=gcf(x,y);cout t=t endl;,void f1(int a,in b)int z;z=gcf(a,b);,放在头文件中,习惯上,main函数总是写在程序的最前面,这样程序比较容易阅读.函数声明采用头文件包含到当前程序中,如 head1,head1 文件的内容:,int gcf(int m,int n);,实际上,标准库函数的声明就用这种方式,如sin等函数在cmath文件中定义,因此要用:,#include,函数的调用,第4章 函数与预处理,函数调用的一般格式:
9、,函数名(实际参数列表),如:printf(%dn,x);,t=gcf(x,y);,函数调用方式:,单独的语句,PrnTime();,表达式的一部分,z=3.5*sin(x);,作为函数的实参,#include using namespace std;int max(int a,int b)return ab?a:b;,void main()int x,y,z;cin x y z;coutMax=max(max(x,y),z);,#include using namespace std;int gcf(int m,int n);/函数声明void main(void)int x,y,t;cou
10、tx y;/函数调用t=gcf(x,y);cout gcf=t endl;,函数调用的例子,第4章 函数与预处理,例4.1,/函数定义int gcf(int m,int n)int r;while(r=m%n)!=0)m=n;n=r;return n;,运行程序,函数的参数,形参与实参,参数传递的几点规定:,形参是虚拟的,在函数被调用之前,它并不占用内存.当函数被调用时,系统为形参分配内存,将实参的值传递给形参.以gcf()函数为例,传递过程如右图.,第4章 函数与预处理,若形参是普通变量(包括指针变量),则实参可以是常量、变量或表达式;,实参的形式,若形参是引用型变量,则实参必须是左值量.,
11、实参与形参的顺序必须保持一致,实参数目一般与形参数目相同,但如果带有默认参数,则实参数目可以少于形参数目.对应参数的类型最好一致,如果实参与形参的类型不一致,则按赋值规则自动将实参类型转换成形参类型.,参数传递的几点规定(续),第4章 函数与预处理,例4.2 采用下面的方法来交换两个变量的值是做不到的!,参数传递采用“值传递”方式.如果形参是普通变量,则将实参的值复制到形参;如果形参是指针变量,则将实参的值(地址)复制到形参;如果形参是引用变量,则将形参看作实参,不再为形参分配内存.,void swap(int m,int n)int t;t=m;m=n;n=t;,#include using
12、 namespace std;void swap(int m,int n);void main(void)int x,y;coutx y;swap(x,y);coutx=x,;couty=yendl;,如果输入:1 3则输出为:x=1,y=3,运行程序,函数的默认参数,什么是默认参数,如果在声明或定义函数时,给形参指定一个值,在调用函数时,如果该形参对应的实参空缺,就采用该指定值,这种参数称为默认参数.,第4章 函数与预处理,默认参数的例子,#include using namespace std;floatsum(float a,float b,float c,int iFlag=0)ret
13、urn a+b+c+5.0*iFlag;void main(void)float x,y,z,s;coutx y z;s=sum(x,y,z);/普通考生/s=sum(x,y,z,1);/1-类考生coutsum=sendl;,例4.3 计算考生三门课程的总分.如果是类考生,加附加分5分;若是类考生,加附加分10分;其他考生不加分.,默认值可包含常量、静态或外部变量,或对其它函数的调用;可以在函数原型声明或函数定义时规定默认值,但两者只能取其一,且必须在调用函数之前指定;只有函数最右边的参数才能默认;如,下面的用法是不对的:void setv(int a,int v1=0,int v2);,默
14、认参数的规则,运行程序,函数的嵌套调用,函数不能嵌套定义,但可以嵌套调用,如下例.,例4.4 用二分法求方程 2x3-4x2+3x-6=0 在-10,10之间的根.,#include#include#include using namespace std;doubleroot(double a,double b,double er,double ev);double f(double x);void main(void)double a=-10,b=10,er=1.e-4,ev=1.e-6,r;if(f(a)*f(b)0.0)cout No root at all!endl;elser=roo
15、t(a,b,er,ev);cout setiosflags(ios:fixed)setprecision(4);,第4章 函数与预处理,例4.4(续),double root(double a,double b,double er,double ev)double fa,fc,c;fa=f(a);doc=0.5*(a+b);fc=f(c);if(fabs(fc)0.0)a=c;elseb=c;while(fabs(b-a)=er);c=0.5*(a+b);return c;double f(float x)return(2*x-4)*x+3.)*x-6.0;,运行程序,cout Root:r
16、endl;,第4章 函数与预处理,三.函数的重载与函数模板,函数的重载,函数重载的概念,通常,函数名总是与实际意义相符合,这样可以顾名思义.如,求两个数的最大值,可定义为max.,第4章 函数与预处理,在C语言中,在同一个作用域中函数名不能重复,这样,求两个int型量的最大值与两个double型量的最大值,必须定义成不同的函数.,C+允许在同一个作用域中,有多个同名的函数,这就是函数重载.这些同名的函数称为重载函数族.,重载可用于一般函数,也可以用于类成员函数,还可以用于运算符,如,等.,重载函数的参数个数或参数类型不能完全一致,这样,编译系统可以根据实参的数目与类型调用与之相匹配的函数.,注
17、.,重载函数举例,#include using namespace std;int add(int,int);int add(int,int,int);double add(double,double);,第4章 函数与预处理,例4.5 求几个数的总和并返回.,void main(void)int a,b,c,d;double x,y,z;cout ab c;d=add(a,b,c);cout xy;z=add(x,y);coutx+y=zendl;,int add(int a,int b)return a+b;,double add(double a,double b)return a+b;
18、,int add(int a,int b,int c)return a+b+c;,若输入:1 3 511 22,则输出:1+3+5=91+3=411+22=33,运行程序,注.若定义了函数:int add(int,int,int=0);则不能再定义:int add(int,int);,函数模板,第4章 函数与预处理,函数模板的概念,对于函数体代码相同,参数个数相同,但返回类型不同,参数类型不同的函数,C+允许定义一个虚拟的函数来统一实现函数的代码.这就是函数模板.在调用函数时,编译系统会根据实参及返回值的类型自动生成相应的函数.,定义函数模板的一般格式,template 普通函数的定义,固定写
19、法,template 普通函数的定义,或者,说明,typename和class两个用法等价,现在前者用得较多;调用模板的函数与模板函数必须在同一文件中;定义模板函数后,不能再定义与其重复的函数.,模板函数举例,#include using namespace std;template T1 add(T1 a,T2 b);/函数声明void main(void)int a,b,c;double x,y,z;couta b;c=add(a,b);coutx y;z=add(x,y);cout T1 add(T1 a,T2 b)return a+b;,第4章 函数与预处理,例4.6 求两个不同类型的
20、数之和并返回.,若输入:5 202.5 3.2,则输出:5+20=252.5+3.2=5.75+2.5=7,运行程序,四.函数的递归调用,一个函数直接或间接调用自身,称为递归调用.这样的函数称为递归函数(Recursive function).,递归的两种形式,直接递归:在函数f()的函数体中直接调用f()自身.,递归的特点:递归是函数的循环调用,因此必须要有结束条件;另外,递归要占用较多的堆栈空间来存放函数的参数.,例4.7:求n!,float factorial(int n)float f=1.0;int i;for(i=2;i=n;i+)f*=i;return f;,第4章 函数与预处理
21、,方法一.递推法,方法二.递归法,float factorial(int n)if(n=1)return 1.0;/递归结束条件elsereturn n*factorial(n-1);,由 n!=n*(n-1)!方法来计算,已知n=1时,n!=1.,运行程序,递归函数的执行过程剖析,递归函数的执行分“回推”和“递推”两个阶段.以5!为例,执行过程如下:,回推过程中的实参5,4,3,2,1 被存放在堆栈(stack)内.,递推时将实参1,2,3,4,5依次从堆栈内释放.,第4章 函数与预处理,递归是对自身函数的反复调用,可能会引起重复计算,另外会消耗大量的堆栈空间.因此,如果能较方便地转换成递推
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 函数与预处理 函数 预处理 PPT 课件

链接地址:https://www.31ppt.com/p-5469817.html