课函数设计教学课件

上传人:无*** 文档编号:240915149 上传时间:2024-05-17 格式:PPT 页数:45 大小:366.50KB
返回 下载 相关 举报
课函数设计教学课件_第1页
第1页 / 共45页
课函数设计教学课件_第2页
第2页 / 共45页
课函数设计教学课件_第3页
第3页 / 共45页
点击查看更多>>
资源描述
第第4章章 函数设计函数设计l函数的定义和声明函数的定义和声明2020/10/161.函数的定义和声明4.1.1 函数的定义函数的定义函数是一个命名的程序代码块,是程序完成其操作的场所,是将功能重复的程序段抽象出来所形成一个独立的、可重复使用的功能模块。定义函数的一般格式为:定义函数的一般格式为:返回类型 函数名(数据类型1 参数1,数据类型2 参数2,.)语句序列;形参表F说明说明:函数必须先定义才可以使用定义函数就是编写完成函数功能的程序块。2020/10/162在C+中,函数原型声明原则如下:(1)如果函数定义在先,调用在后,调用前可以不必声明;如果函数定义在后,调用在先,调用前必须声明。(2)在程序设计中,为了使程序设计的逻辑结构清晰,一般将主要的函数放在程序的起始位置声明,这样也起到了列函数目录的作用。声明函数原型的形式如下:声明函数原型的形式如下:例如:例如:intmax(intx,inty);intmax(int,int);.1.2.1.2 函数原型的声明函数原型的声明 返回类型 函数名(数据类型1 参数1,数据类型2 参数2,.);加上参数名会使函数的加上参数名会使函数的功能和参数更清晰。功能和参数更清晰。2020/10/1634.2 4.2 函数参数的按值传递函数参数的按值传递 函数调用过程实际上执行了一个从参数传递-执行函数体-返回的过程。其中的函数参数传递过程的实质是将实参值通过栈空间一一传送给实参的过将实参值通过栈空间一一传送给实参的过程程,这种把实参表达式的值传送给对应的形参变量传递方式称为“按值传递按值传递”。2020/10/164/*p4_2.cpp*函数的传值调用,将两个数交换*/#includeusingnamespacestd;void s a,int b)intt;t=a,a=b,b=t;void main()intx=7,y=11;coutx=xy=yendl;s);coutafterswap:;coutx=xy=yendl;12345678910111213141516171819函数定义函数定义传值调用传值调用 运行结果运行结果运行结果运行结果:x=7 y=11after swap:x=7 y=112020/10/1654.3 函数的传递函数的传递参数参数 C C语言中,函数的参数和返回值的传递方式有两种:语言中,函数的参数和返回值的传递方式有两种:值传递(值传递(pass by value)和指针传递()和指针传递(pass by pointer)。)。C+语言中多了引用传递(语言中多了引用传递(pass by reference)。)。2020/10/166【规则【规则4-1-1】参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字。如果函数没有参数,则用void填充。例如:例如:voidSetValue(intwidth,intheight);/良好的风格voidSetValue(int,int);/不良的风格floatGetValue(void);/良好的风格floatGetValue();/不良的风格2020/10/167【规则【规则4-1-2】参数命名要恰当,顺序要合理。例如编写字符串拷贝函数StringCopy:void StringCopy(char*str1,char*str2);那么我们很难搞清楚究竟是把str1拷贝到str2中,还是刚好倒过来!2020/10/168可以把参数名字起得更有意义,如叫strSource和strDestination。这样从名字上就可以看出应该把strSource拷贝到strDestination。void StringCopy(char*strDestination,char*strSource);还有一个问题,这两个参数那一个该在前那一个该在后?参数的顺序要遵循程序员的习惯。一般地,应将目的参数放在前面,源参数放在后面。2020/10/169【规则【规则4-1-3】如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。例如:void StringCopy(char*strDestination,const char*strSource);2020/10/16104.4 返回值的规则返回值的规则【规则【规则4-2-1】不要省略返回值的类型。C语言中,凡不加类型说明的函数,一律自动按整型处理。这样做不会有什么好处,却容易被误解为void类型。C+语言有很严格的类型安全检查,不允许上述情况发生。由于C+程序可以调用C函数,为了避免混乱,规定任何C+/C函数都必须有类型。如果函数没有返回值,那么应声明为void类型。2020/10/1611【规则【规则4-2-2】不要将正常值和错误标志混在一起返回。正常值用输出参数获得,而错误标志用return语句返回。如,if(in=fopen(,rt)=0)printf(无法打开指定输入文件!无法打开指定输入文件!n);return 1;2020/10/1612【规则【规则4-2-3】在函数体的“出口处”,对return语句的正确性和效率进行检查。return语句不可返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。2020/10/1613程序在内存中的区域分布程序在内存中的区域分布 存放程序代码存放程序的全局数据和静态数据存放程序的动态数据存放程序的局部数据2020/10/1614例如例如char*Func(void)char str=“hello world”;/str的的内内存存位位于于栈栈上上 return str;/将导致错误将导致错误2020/10/1615【建建议议4-1-1】函数的功能要单一,不要设计多用途的函数。【建建议议4-1-2】函数体的规模要小,尽量控制在50行代码之内。2020/10/1616【建建议议4-1-3】尽量避免函数带有“记忆”功能。相同的输入应当产生相同的输出。在C/C+语言中,函数的static局部变量是函数的“记忆”存储器。建议尽量少用static局部变量,除非必需。2020/10/1617【建议【建议4-1-4】用于出错处理的返回值一定要清楚,让使用者不容易忽视或误解错误情况。2020/10/16184.5 引用与指针引用与指针l引用的概念 引用就是取别名,如:n是m的一个引用(reference),m是被引用物,则int m;int m;int&n=m;int&n=m;2020/10/1619ln相当于m的别名(绰号),对n的任何操作就是对m的操作。例如有人名叫王小毛,他的绰号是“三毛”。说“三毛”怎么怎么的,其实就是对王小毛说三道四。所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。2020/10/1620引用的用法引用的用法l引用在声明时必须被初始化,否则会产生编译错误。int m;int m;int&n=m;int&n=m;/正确正确 int&n;int&n;/错误错误 2020/10/1621定义引用与变量的关系voidmain()int m;int m;int&n=m;int&n=m;m=5;m=5;2020/10/1622l引用的主要功能是传递函数的参数和返回值。2020/10/1623l引用与指针的区别引用与指针的区别:(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。2020/10/1624 以下示例程序中,k被初始化为i的引用。int i=5;int i=5;int j=6;int j=6;int&k=i;int&k=i;k=j;k=j;/k和i的值都变成了6;语句k=j并不能将k修改成为j的引用,只是把k的值改变成为6。2020/10/1625l函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。2020/10/1626“值传递值传递”的示例程序的示例程序 void Func1(int x)void Func1(int x)x=x+10;x=x+10;int n=0;int n=0;Func1(n);Func1(n);cout “n=”n endl;cout “n=”n endl;/n=0/n=0 2020/10/1627“指针传递指针传递”的示例程序的示例程序 void Func2(int*x)void Func2(int*x)(*x)=(*x)+10;(*x)=(*x)+10;int n=0;int n=0;Func2(&n);Func2(&n);cout “n=”n endl;/n=10cout “n=”n endl;/n=10 2020/10/1628“引用传递引用传递”的示例程序的示例程序 void Func3(int&x)void Func3(int&x)x=x+10;x=x+10;int n=0;int n=0;Func3(n);Func3(n);cout “n=”n endl;cout “n=”n endl;/n=10/n=10 2020/10/1629l对比上述三个示例程序,会发现“引用传递”的性质象“指针传递”,而书写方式象“值传递”。实际上“引用”可以做的任何事情“指针”也都能够做,为什么还要“引用”这东西?l答案是“用适当的工具做恰如其分的工作用适当的工具做恰如其分的工作”!2020/10/1630l如果的确只需要借用一下某个对象的“别名”,那么就用“引用”,而不要用“指针”,以免发生意外。l比如说,某人需要一份证明,本来在文件上盖上公章的印子就行了,如果把取公章的钥匙交给他,那么他就获得了不该有的权利。2020/10/16314.6 函数的嵌套调用/*函数的嵌套调用,求三个数中最大数和最小数的差值*/#includeusingnamespacestd;int max(int x,int y,int z)intt;t=xy?x:y;return(tz?t:z);123456789101112函数定义函数定义 在一个函数中调用其它函数叫函函数数的的嵌嵌套套。C+中函数的定义是平行的,除了main()以外,都可以互相调用。函数不可以嵌套定义,但可以嵌套调用。2020/10/1632int min(int x,int y,int z)intt;t=xy?x:y;return(tabc;coutMax-Min=dif(a,b,c)0)递归可以分为直接递归调用和间接递归调用。直接递归调用直接递归调用:是在调用函数的过程中又调用该函数本身;间接递归调用间接递归调用:是在调用f1()函数的过程中调用f2()函数,而f2()中 又需要调用f1()。4.7 函数的递归调用 2020/10/1634递归函数设计的一般形式是:函数类型 递归函数名f(参数x)if(满足结束条件)结果=初值;else 结果=含f(x-1)的表达式;返回结果;递归方法是从结果出发,归纳出后一结果与前一结果直到初值为止存在的关系,要求通过分析得到:初值初值+递归函数递归函数,然后设计一个函数(递归函数),这个函数不断使用下一级值调用自身,直到结果已知处。2020/10/1635/*函数的递归调用,求n!*/#includeusingnamespacestd;int fac(int n)intt;if(n=1)t=1;elset=n*fac(n-1);return(t);123456789101112131415递归函数定义递归函数定义2020/10/1636void main()constintmax_n=12;/int类型数能表示的n!的最大的nintn;coutn;if(n=1&n=max_n)coutFactorialofnis:fac(n)endl;elsecoutInvalidn.endl;16171819202122232425递归函数调用递归函数调用运行结果运行结果运行结果运行结果:12479001600 递归程序分两个阶段执行:调用调用:欲求fac(n)先求fac(n-1)fac(n-2)fac(1)若fac(1)已知,回推结束。回代回代:知道fac(1)可求出fac(2)fac(3)(n)2020/10/1637函数参数传递过程:2020/10/1638内联函数的定义形式如下:4.8 内联函数 inline 函数类型 函数名(形式参数表)函数体;内联函数:内联函数:是通过在编译时将函数体代码插入到函数调用处,将调用函数的方式改为顺序执行方式来节省程序执行的时间开销,这一过程叫做内内联联函数的扩展函数的扩展。因此,内联函数实际上是一种用空间换时间的方案。在内联函数扩展时也进行了实参与形参结合的过程:先将实参名(而不是实参值),与函数体中的形参名替换,然后搬到调用处。但从用户的角度看,使用内联函数和一般函数没有任何区别。2020/10/1639/*内联函数的使用*/#includeusingnamespacestd;inline double CirArea(double radius)return3.14*radius*radius;void main()doubler1(1.0),r2(2);coutCirArea(r1)endl;coutCirArea(r1+r2+4)endl;12345678910111213141516内联函数定义内联函数定义内联函数调用内联函数调用运行结果运行结果运行结果运行结果:3.14153.86 2020/10/1640注意:如果仅在声明函数原型时加上关键字inlineinline,并不能达到内联效果。内联函数的定义必须出现在对该函数的调用之前!因为编译器在对函数调用语句进行替换时,必须事先知道替换该语句的代码是什么。这也是仅在声明函数原型时加上关键字inline,并不能达到内联效果的原因。由于计算机的资源总是有限的,使用内联函数虽然节节省省了程序运行的时间开销,但却增增大大了代码占用内存的空间开销。因此在具体编程时应仔细地权衡时间开销与空间开销之间的矛盾,以确定是否采用内联函数。2020/10/16414.9 函数重载 intmax(int,int);intmax(int,int,int);floatmax(float,float);doublemax(double,double);函数重载:函数重载:就是两个以上的函数,取相相同同的的函函数数名名,但是形形参参的的个个数数和和类类型型不不同同,编译器根据实参和形参的类型及个数的最佳匹配最佳匹配,自动决定调用哪一个函数。例如:2020/10/1642/*函数的重载*/#includeusingnamespacestd;int add(int x,int y)cout(int,int)t;returnx+y;double add(double x,double y)cout(double,double)t;returnx+y;int add(int x,double y)cout(int,double)t;returnint(x+y);123456789101112131415161718192021函数重载函数重载函数重载函数重载函数重载函数重载2020/10/1643double add(double x,int y)cout(double,int)t;returnx+y;void main()coutadd(9,8)endl;coutadd(9.0,8.0)endl;coutadd(9,8.0)endl;coutadd(9.0,8)endl;212223242526272829303132函数重载函数重载运行结果运行结果运行结果运行结果:(int,int)17(double,double)17(int,double)17(double,int)17 重载函数的调用重载函数的调用2020/10/1644THANKSFOR WATCHING谢谢大家!本文档为精心编制而成,您可以在下载后自由修改和打印,希望下载对您有帮助!演讲人:XXXPPT文档教学课件
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!