辅导5-函数
- 格式:doc
- 大小:108.00 KB
- 文档页数:15
函数一、函数的定义1、函数概念的引入1)举例:计算圆面积的c程序#i n c l u d e<s t d i o.h>v o i d m a i n(){d o u b l e r=5.0;d o u b le a r e a=3.14159*r*r;p r i n t f(”圆面积为:%f\n”,a r e a);}抽取计算圆面积的算法作为独立程序段,程序可改为:1.#i n c l u d e<s t d i o.h>2.d o u b l e C a l A r e a()//2~6行是C a l A r e a函数功能的描述(定义)3.{d o u b l e r=5.0;//这个函数只能计算半径为5的圆的面积4.d o u b l e a r e a=3.14159*r*r;5.r e t u r n a r e a;6.}7.v o i d m a i n()8.{d o u b l e a r e a=C a l A r e a();//执行C a l A r e a函数9.p r i n t f(”圆面积为:%f\n”,a r e a);10.}修改C a l A r e a()函数,使半径的值由主函数决定1.#i n c l u d e<s t d i o.h>2.d o u b l e C a l A r e a(d o u b l e r)//r为函数C a l A r e a的形式参数3.{d o u b l e a r e a=3.14159*r*r;4.r e t u r n a r e a;5.}6.v o i d m a i n()7.{d o u b l e a r e a=C a l A r e a(5);//5为函数C a l A r e a的实在参数8.p r i n t f(”圆面积为:%f\n”,a r e a);9.}修改主函数,使程序可以计算半径不同的圆的面积1.#i n c l u d e<s t d i o.h>2.d o u b l e C a l A r e a(d o u b l e r)//r为函数C a l A r e a的形式参数3.{d o u b l e a r e a=3.14159*r*r;4.r e t u r n a r e a;5.}6.v o i d m a i n()7.{d o u b l e r a d i u s;8.p r i n t f(”请输入半径”);9.s c a n f(“%f”,&r a d i u s);10.d o u b l e a r e a=C a l A r e a(r a d i u s);//r a d i u s为函数的实在参数11.p r i n t f(”圆面积为:%f\n”,a r e a);12.}2)函数的作用●降低难度及复杂度,实行分工合作,各尽其职●便于进行分级管理,简化程序设计3)C程序的执行总是从m a i n()开始,最后总是在m a i n()结束(不论m a i n()的位置)程序结束2、函数的定义1)定义格式返回类型函数名(形参表){函数体}d o u b le A r e a(d o u b l e r){r e t u r n3.1415*r*r;}2)函数参数●含义:是函数完成功能所需要的输入信息●参数类型:形式参数实在参数●组成:形式参数:类型参数1,类型参数2,……,类型参数n实在参数:参数1,参数2,…,参数n3)返回类型●含义:函数运行结束返回一个结果值,该值的数据类型●类型包括:除数组外所有数据类型(默认类型为i n t)4)函数体●含义:是函数功能的实现(描述)●组成:语句5)函数的类型●无参函数/有参函数无参函数类型函数名(){函数体}有参函数类型函数名(形参表){函数体}●无返回值/有返回值无返回值v o i d函数名(形参表){……r e t u r n;}或v o i d函数名(形参表){…}有返回值返回值类型函数名(形参表){……r e t u r n表达式;}3、空函数1)含义:函数体为空的函数2)意义:增加程序的可读性,便于程序的扩充4、r e t u r n语句1)格式:r e t u r n表达式为可选项2)作用:●终止当前函数的执行,返回主调函数●向主调函数返回一个值5、函数原型1)前提:所有标识符都必须遵循“先说明,后使用”的原则。
2)结论:因此在函数的调用前,必须有函数的说明。
3)函数原型与函数定义的区别●函数定义——定义性说明“从无到有”——提供函数的所有信息●函数原型——参考性说明“提供函数调用所需的接口信息”●定义只能有一次,但声明可以多次出现4)函数原型语句的格式:返回类型函数名(形参表);5)函数能正确调用的条件:函数的定义位于调用之前或函数的原型位于调用之前6)必须使用函数原型的情况●多文件程序●函数递归调用●使用库函数二、函数调用1、函数的调用1)调用格式:函数名(实参表);实参出现在主调函数中形参出现在被调函数中2)注意:●实参与形参的个数要相同,类型要一致(兼容),且一一对应●常量形参(c o n s t):函数体中不能改变该形参的值。
3)调用方式:作为表达式(必须是有返回值的函数)/作为语句调用2、调用过程1)参数传递2)执行函数体3)函数返回3、参数传递机制(赋值)1)传值调用形式 对应关系实参 表达式(有确定值) 值形参 变量(存储单元) 变量2) 传地址调用形式 对应关系实参 变量的地址 地址 形参 变量 指针● 数组名作为实参传递的是数组的首地址。
三、 程序运行时的内存分布● 程序运行时的内存分布程序的源代码(系统支配的空间)全局变量和静态变量(系统支配的空间)由程序控制,可在运行中由语句动态分配(malloc )及回收(free )被调用的函数信息,局部变量 (程序支配的空间) 注:红色为数据区,在全局数据区的数据,若没初始化,自动取值为0; 堆、栈区的数据,若没初始化,其值为随机值。
四、函数调用的实现机制1、函数调用时系统执行的操作:●建立被调用函数的栈空间●保护断点(主调函数的运行状态、返回地址)●参数传递●被调用函数取得程序的控制权2、函数执行结束后系统执行的操作:●若有返回值,将它存到一个临时的空间●恢复断点(主调函数的运行状态、返回地址)●释放相应(调用函数所占)的栈空间●继续执行主调函数五、作用域1、作用域:标识符在程序中起作用(能被使用)的范围●全局作用域:始于声明点,终于程序(程序中一般都含有多个.c p p)的结束。
●文件作用域(s t a t i c):始于声明点,终于本文件(.c p p)结束处●局部(块)作用域:始于声明点,终于“块”结束处2、存储属性:1)静态:全局变量、s t a t i c变量2)动态:堆变量、自动变量、函数的形参、寄存器变量3、变量的作用域1)全局变量:在函数之外定义●无限制:可供程序中的所有函数使用●有限制:文件域变量--只供本文件中的所有函数使用2)局部变量:在复合语句内定义,仅能在该复合语句内使用3)覆盖问题:●内层的同名变量总是覆盖外层的同名变量●作用域小覆盖作用域大的4)归纳4、生命期(生存期):标识符存在(创建到删除之间)的时间。
●静态生命期:全局变量、静态变量、常量特点:编译时分配空间,程序运行结束才释放空间●动态生命期:非静态的局部变量——栈区中的变量特点:在函数调用时分配存储单元,函数结束就释放空间 动态生命期:使用m a l l o c()等函数分配空间的变量特点:程序运行中随时根据需要申请分配空间、释放空间(f r e e)5、举例:例1:#i n c l u d e"s t d i o.h"v o i d f u n(i n t,i n t);v o i d m a i n(){i n t a,b;//这个a,b是内部(局部)变量,有效范围(作用域)在此处开始到m a i n结束(})a=5;b=8;f u n(a,b);p r i n t f("主函数中:a=%d,b=%d\n",a,b);}v o i d f u n(i n t a,i n t b)//这个a,b是内部(局部)变量,有效范围(作用域)在此处开始到f u n结束()){i n t c;//c是内部(局部)变量,有效范围(作用域)在此处开始到f u n结束(})c=a;a=b;b=c;p r i n t f("f u n函数中:a=%d,b=%d\n",a,b);}f u n也可写成:v o i d f u n(i n t x,i n t y)//这个x,y是局部变量,有效范围(作用域)在此处开始到f u n结束(}){i n t c;//c是局部变量,有效范围(作用域)在此处开始到f u n结束()}c=x;x=y;y=c;p r i n t f("f u n函数中:a=%d,b=%d\n",x,y);}例2:t e s t6_8_2.c:#i n c l u d e"s t d i o.h"v o i d f u n();i n t a,b;//这个a,b是外部(全局)变量,有效范围(作用域)在此处开始到t e s t6_8_2.c文件的最后一行v o i d m a i n(){a=5;b=8;f u n();p r i n t f("主函数中:a=%d,b=%d\n",a,b);}v o i d f u n(){i n t c;//c是内部(局部)变量,有效范围(作用域)在此处开始到f u n结束(})c=a;a=b;b=c;p r i n t f("f u n函数中:a=%d,b=%d\n",a,b);}例3:程序1:a.c#i n c l u d e"s t d i o.h"v o i d f u n();i n t a,b;//这个a,b是外部(全局)变量,有效范围(作用域)在此处开始到程序结束v o i d m a i n(){a=5;b=8;f u n();p r i n t f("主函数中:a=%d,b=%d\n",a,b);}程序2:b.ce x t e r n i n t a,b;//两个函数不在同一个程序中,要使用其他程序中定义的外部(全局)变量,需要做出声明v o i df u n(){i n t c;//c是内部(局部)变量,有效范围(作用域)在此处开始到f u n结束(})c=a;a=b;b=c;p r i n t f("f u n函数中:a=%d,b=%d\n",a,b);}例4:程序1:a.c#i n c l u d e"s t d i o.h"v o i d f u n();s t a t i c i n t a,b;//这个a,b是静态外部(全局)变量,有效范围(作用域)限制在a.c中v o i d m a i n(){a=5;b=8;f u n();p r i n t f("主函数中:a=%d,b=%d\n",a,b);f u n();p r i n t f("主函数中:a=%d,b=%d\n",a,b);}程序2:b.ce x t e r n i n t a,b;//虽然做出声明,但无法使用a.c中定义的静态外部变量v o i d f u n(){i n t c;//c是内部(局部)变量,有效范围(作用域)在此处开始到f u n结束(})c=a;a=b;b=c;p r i n t f("f u n函数中:a=%d,b=%d\n",a,b);}例5:#i n c l u d e"s t d i o.h"i n t a,b;//这个a,b是外部(全局)变量,初始值为0,它们的作用范围是整个程序v o i d f u n();v o i d m a i n(){i n t a,b;//这个a,b是内部(局部)变量,初始值为随机值b=8;//当外部变量和内部变量作用范围重合时,内部起作用f u n();p r i n t f("主函数中:a=%d,b=%d\n",a,b);//在m a i n范围中,局部变量a,b起作用}v o i d f u n(){a++;b--;p r i n t f("f u n函数中:a=%d,b=%d\n",a,b);}例6:#i n c l u d e"s t d i o.h"v o i d f u n();v o i d m a i n(){i n t i;f o r(i=1;i<=5;i++)f u n();}v o i d f u n(){i n t a=0;//a是内部(局部)变量,每次调用f u n函数,a重新分配空间s t a t i c i n t b=0;//b是静态内部(局部)变量,它的值一直保留到程序结束a++;b++;p r i n t f("a=%d,b=%d\n",a,b);}//a和b的作用范围只在f u n函数中六、函数的递归调用1、递归调用的含义:直接或间接地调用函数本身。