第5章 函数机制.ppt
《第5章 函数机制.ppt》由会员分享,可在线阅读,更多相关《第5章 函数机制.ppt(166页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Visual C+Program Design第五章第五章 函数机制函数机制 Chapter 5 Function MechanismVisual C+Program Design2 函数的简介函数的简介v创建程序的语句块v在不同的程序设计语言中的名称:Procedures,subprograms,methodsInC+:functionsvI-P-OInputProcessOutput任何程序中的基本构件使用函数来完成Visual C+Program Designv函数 C+的函数是完成既定任务的功能(过程)体,它涵盖了数学函数和一般过程所以基于过程编程本质上就是基于函数编程v函数机制 一是
2、指程序运行过程中对函数调用的数据管理和处理过程 二是指编程中函数的使用规范它包括函数参数的属性和传递规则,函数返回类型的匹配与审查,函数名字的识别原则,函数体效率的选择,函数体中数据的访问权限等Visual C+Program Design4预定义的函数预定义的函数vC+提供了预定义的函数库!v两种类型:返回(产生)值的函数无返回值的函数(void函数)v许多“#include”包含合适的函数库e.g.,(最初的“C”语言库)(forcout,cin)Visual C+Program Design5程序员定义的函数程序员定义的函数v写自己的函数!v程序的子部分单独&复合可读性可重用v你所定义的
3、函数:放在main()的主函数文件中也可以单独放在一个其他的文件中来调用Visual C+Program Design6使用函数的组成部分使用函数的组成部分v函数使用的3个部分:函数声明/函数原型提供给编译器必要的信息使用一个函数调用所需要知道的内容函数定义实际执行的函数代码函数调用函数的控制转移Visual C+Program Design7函数声明函数声明v也称为函数原型v一个给编译器的“信息”声明v告诉编译器调用的含义语法:FnName();例如:doubletotalCost(intnumberParameter,doublepriceParameter);v在调用前放置的位置放在ma
4、in()中的声明空间或者放在main()前,在全局空间中Visual C+Program Design8函数的声明函数的声明v函数是面向对象程序设计中,对功能的抽象v函数声明的语法形式类型标识符 函数名(形式参数表)语句序列函数的声明与使用是被初始化的内部变量,寿命和可见性仅限于函数内部若无返回值,写voidVisual C+Program Design9函数的声明函数的声明v形式参数表 name1,name2,.,namenv函数的返回值由 return 语句给出,例如:return 0无返回值的函数(void类型),不必写return语句。函数的声明与使用Visual C+Program
5、Design10函数定义函数定义v函数执行v就像main()主函数的执行v例如:doubletotalCost(intnumberParameter,doublepriceParameter)constdoubleTAXRATE=0.05;doublesubTotal;subtotal=priceParameter*numberParameter;return(subtotal+subtotal*TAXRATE);v注意合适的缩进Visual C+Program Design11函数定义放置的位子函数定义放置的位子v放在main()主函数后不要“插在”main()函数中!v函数都是“平等的”;
6、没有函数是另一个函数的一“部分”函数的定义如同一个小程序,调用一个函数相当于运行这个小程序。v定义中的形式参数数据传送的“占位符”,利用形参来输入。函数的实参就是实际输入的值,它们会在形参的位置插入。v返回语句返回给调用者数据,函数会返回一个值,就好像函数的“输出”Visual C+Program DesignVisual C+Program DesignVisual C+Program Design14函数调用函数调用v就和调用预定义函数一样bill=totalCost(number,price);v被调用:totalCost返回double类型赋值给变量名billv这里的实参:number
7、,price被调实参可以是文字常量,变量,表达式或者它们的组合被称为实参是因为它们是真正被传送的数据Visual C+Program Design15函数的调用函数的调用v调用前先声明函数原型:在调用函数中,或程序文件中所有函数之外,按如下形式说明:类型标识符 被调用函数名(含类型说明的形参表);v调用形式 函数名(实参列表)v嵌套调用函数可以嵌套调用,但不允许嵌套定义。递归调用函数直接或间接调用自身。函数的声明与使用Visual C+Program Design16调用函数的函数调用函数的函数v经常使用!main()就是一个函数!v必要条件:函数声明必须在使用函数之前完成v函数的定义放置的在
8、在main()函数定义之后或者在其他文件中,使函数能由几个不同的程序使用。v函数也可能调用自身“递归“v函数声明可以放在*.h文件中Visual C+Program DesignVisual C+Program Design18例例3-5函数的声明与使用Visual C+Program Design#include#includeusing namespace std;double tsin(double x);int main()double k,r,s;coutr;couts;if(r*r=s*s)k=sqrt(tsin(r)*tsin(r)+tsin(s)*tsin(s);else k=
9、tsin(r*s)/2;coutk=p);return g;运行结果:r=5s=81.3778120Visual C+Program Design21函数调用的执行过程函数调用的执行过程函数的声明与使用main()调fun()结束fun()返回保存:返回地址当前现场恢复:主调程序现场返回地址Visual C+Program Design22嵌套调用嵌套调用函数的声明与使用main调 fun1()结束fun1()调 fun2()返回fun2()返回Visual C+Program Design第五章内容第五章内容1.函数性质函数性质(Function Character)2.指针参数指针参数(P
10、ointer Parameters)3.栈机制栈机制(The Stack Mechanism)4.函数指针函数指针(Function Pointers)5.命令行与命令行与main参数参数(Command line&The mains Arguments)6.递归函数递归函数(Recursive Functions)7.函数重载函数重载(Function Overload)Visual C+Program Design5.1.1 函数的形态函数的形态v有些函数具有求值表现,即有返回值,它可以无输入参数,也可以带多个或一个参数。如:-x x02 x0 x2 x0-x +f(x)=v等价的C+函数
11、描述为:longdoublef(longdoublex)if(x0)returnx*x;return2;v数学函数定义域为,而long double为 1.2104932,所以参数表示范围为大于0时的平方根:-1.2104932x1.1102466Visual C+Program Designv也有一些函数没有求值表现,无返回值。如:voidprint()cout“unsignedintf(unsignedintn)n”“if(n=1|n=2)return1;n”“returnf(n-1)+f(n-2);n”“n”;也有一些表现为过程的函数,具有参数,如延迟n秒的函数:voiddelay(in
12、tn)for(inti=0;in;i+)for(intj=0;j100000000;j+);/该循环约耗时1秒Visual C+Program Design跨越数学函数的跨越数学函数的C+函数,有四种形态函数,有四种形态v返回类型func(参数列表);v返回类型func();vvoidfunc(参数列表);vvoidfunc();Visual C+Program Designv有返回类型的函数可以参加表达式运算,或者直接赋值给对应类型的变量,构成表达式语句。如:doubles=sin(b)+1;/s定义语句中的函数调用s=cos(c)/2;/s赋值语句v无返回值类型的函数,不能以值的形式赋给其
13、它变量或者参加运算,其调用只能独立构成一条语句,如:print();/okintt=print();/错Visual C+Program Designv需要时,有返回类型的函数也可以像无返回类型的函数一样单独构成语句,如:chars130;chars2=“hello”;strcpy(s1,s2);/单独构成语句,完成复制工作coutm?m:n)*10;/保证运输次数最少Visual C+Program Designv函数通过参数来传递输入数据,参数通过传值机制来实现。所谓传值即在函数被调用之时,用克隆实参的办法来创建形参。如:5.1.3 传值参数传值参数Visual C+Program Des
14、ign参数传递:形参是对实参的克隆,克隆必须遵守类型匹配规则参数传递:形参是对实参的克隆,克隆必须遵守类型匹配规则void f(Type a);/a为形参void g()Type x;f(x);/x为实参a实体x实体复制Type类型Type类型Visual C+Program Designv当有大数据量的函数进行参数传值的时候,如传递给函数一个数据整体的复制品时,如:vvectormysort(vectorv);vvoidf()inta=3,5,7,1,8,4,9,2,6,0;vectorva(a,a+10);vectorvb=mysort(va);/vectorv=va;大数据量的函数的流程
15、图如图5-2所示:Visual C+Program Design大量数据黑盒大量数据输入函数mySort输出图5-2 大数据流量的函数Visual C+Program Designv上述大数据量的函数有效的方法是传递给mysort排序函数以一个数组指针或者容器引用,这样,传递的是指针和引用值,然后通过指针和引用的间访来实现数据的操作。从而使得函数调用才这么灵活,高效,无须去背大块数据传递的沉重负担,如传递数组的方法:5.2.1 指针和引用参数指针和引用参数Visual C+Program Designvoid mySort(int*b,int size);void f()int a=3,5,7
16、,1,8,4,9;mySort(a,sizeof(a)/sizeof(a0);元素个数传指针Visual C+Program Designv数组是不能整体复制的,即:inta10;intb10=a;/错b=a;/错v数组只能通过传递数组起始地址,达到使用该数组的目的。Visual C+Program Design传递指针:指针参数也是值传递的,指针值的真正用途是进行数据间访,以达到操作数据块(大小由之)的目的传递引用:引用参数本质上也是值传递的,它表现为名字传递,即以形参的名字来代替实参名字如果实参不是实体名而是表达式,那么其表达式所对应的临时实体取名为形参,并要求其为常量引用意义:指针和引用
17、参数的存在,使函数实际上可以访问非局部的数据区,函数的黑盒性便名存实亡但这并非一定坏事,指针是一把双刃剑,或灵巧或邪恶引用是为了防范指针非安全的无意操作Visual C+Program Designv然而,传递指针和引用的特性还是被广泛应用,由于参数值可以通过传递指针和引用获得,所以它意味着函数可以访问不属于自己管辖的数据,如图5-3所示:Visual C+Program Design9481753数组a函数f调用了mySort被调函数mySort参数b指向数组a函数f在mySort返回之后:9875431数组a图5-3 数组传递Visual C+Program Designv只传递数组的地址
18、,减轻了参数传递过程中的数据复制量,但是排序是在数组a上操作的,数据的改变不是在mySort函数数据区内,等到函数返回后,数组a的内容发生了改变,而参数b本身的值却没有任何改变!v这意味着函数运行的结果并不一定要用返回类型规定的返回值来反映,函数参数也能起到返回结果的作用。v函数可以传递多个输入参数,也可以让多个数据处理的对象发生变化。Visual C+Program Design5.2.2 函数的副作用函数的副作用v函数参数传递指针和引用是一把双刃剑,它的副作用是破坏本地的数据,破坏模块性。v函数的黑盒性是指不与外界发生以外沟通,只依赖输入参数,只送出返回结果,因此,它是结果可以重复的计算过
19、程。但是指针和引用的参数传递展示了函数可以访问非本地数据的途径,从而破坏了函数的黑盒性!如:Visual C+Program Designvvoidprint(vector&a)for(inti=0;ia.size;i+)coutai“”;coutendl;/-vectoradd(vector&a,vector&b)for(inti=0;ia.size;i+)ai+=bi;returna;/-intmain()intaa=2,3,1,2,3,2,1,bb=5,3,1,1,6,2,2;vectora(aa,aa+7),b(bb,bb+7);vectorc=add(a,b);print(a);pr
20、int(b);print(c);Visual C+Program Designv结果:762394353116227623943v程序本意是将两个初始化了的数组赋给两个向量a和b,然后调用add相加,并输出这两个向量以及结果向量。但是结果却发现,main函数调用的add函数结果虽然对了,但是原始数据的向量a却被破坏了。这就是函数运行所带来的副作用!Visual C+Program Designv问题就出在规定参数传递的声明上,传递引用,给了函数超限的权力,函数循着传递的引用名而既读又写地访问了引用的空间,而那一片引用空间不是函数所拥有的。因此,对应的手段就是在指针和引用参数上可以加const修
21、饰,以此限制函数体中对参数的写操作。如Visual C+Program Design限制无意操作带来的意外副作用vector add(/向量加法 const vector&a,const vector&b)vector c(a.size();for(unsigned i=0;ia.size();+i)ci=ai+bi;return c;Visual C+Program Designv参数的const声明,框定了传递的参数只能以形参规定的原则来操作。当模块设计或结构设计与编程设计相分离时,所规定的函数参数传递的常量性就能规范编程行为,不致产生副作用。Visual C+Program Design
22、5.3.1 运行时内存布局运行时内存布局v一个程序要运行,先将可执行程序文件装载到计算机的内存中。操作系统将程序装入内存后,将形成一个随时可以运行的进程空间,该空间分为四个区域,如图5-4所示:Visual C+Program Design栈区进程空间代码区全局数据区堆区图5-4 运行中的内存布局Visual C+Program Designv代码区存放程序的执行代码v全局数据区存放全局数据、变量、文字量、静态全局量和静态局部量。v堆区存放动态内存,供程序随机申请使用。v栈区存放函数数据区,它动态地反映了程序运行中的函数状态,其运动轨迹正好用来观察函数的调用与返回。Visual C+Progr
23、am Design5.3.2 栈区栈区v栈是一种数据结构,遵循后进先出的原则。vC+的函数调用整个过程就是栈空间操作的过程。函数调用时,C+做下列工作:1.建立被调函数的栈空间,大小由函数定义体中数据量多少而定2.保护被调用函数的运行状态和返回地址3.传递参数4.将控制权转交给被调函数5.函数运行完成后,复制返回值到函数数据块底部6.恢复被调用函数的运行状态7.返回调用函数Visual C+Program Designv调用一个函数,可以看作是一个栈中元素的压栈和退栈操作。v最初,操作系统将main函数压入栈中,标志着程序运行的开始,等到最后main函数退栈,程序也就运行结束了。Visual
24、C+Program Designv下面的程序在main函数中调用一个函数,该函数又调用另一个函数,它得到如图5-5所示的栈结构布局。栈区运动演示程序如下:intfuncA(intx,inty);voidfuncB(int&s);intmain()inta=6,b=12;a=funcA(a,b);intfuncA(intx,inty)intn=5;funcB(n);returnn;voidfuncB(int&s)intx=8;s=x;Visual C+Program Design。局部变量x8形式参数s返回funcA地址funcA状态保护例程指针局部变量n5形式参数y12形式参数x6返回main
25、地址main状态保护例程指针返回值8局部变量b12局部变量a6参数返回操作系统地址操作系统状态保护例程指针操作系统返回值0funcB函数funcA函数main函数图5-5 运行中的函数栈结构Visual C+Program Designvmain函数被OS(操作系统)调用时,在栈中安排了返回值位置,OS状态保护例程指针是指完成恢复工作的函数地址,函数为硬件设置,或为OS专用的函数。在main函数返回时,取其地址调用,然后取OS调用main时的地址,返回调用点。main函数也有参数。Visual C+Program Designvmain函数在进行变量a的赋值运算时调用funcA函数获得函数值。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第5章 函数机制 函数 机制
限制150内