d06函数与编译预处理.ppt

上传人:max****ui 文档编号:11494981 上传时间:2020-04-25 格式:PPT 页数:44 大小:502.50KB
返回 下载 相关 举报
d06函数与编译预处理.ppt_第1页
第1页 / 共44页
d06函数与编译预处理.ppt_第2页
第2页 / 共44页
d06函数与编译预处理.ppt_第3页
第3页 / 共44页
点击查看更多>>
资源描述
模块化程序设计与函数函数的定义与调用函数的嵌套、递归调用变量作用域与存储方式编译预处理函数设计举例,函数与编译预处理,函数,模块化程序设计,在设计较复杂的程序时,我们一般采用的方法是:把问题分成几个部分,每部分又可分成更细的若干小部分,逐步细化,直至分解成很容易求解的小问题。这样的话,原来问题的解就可以用这些小问题来表示。求解小问题的算法和程序称为“功能模块”。在C语言中,这样的“功能模块”是通过函数来实现的,最终函数通过调用完成组合,形成的源程序文件就对应完整的功能要求。函数是C语言程序最基本的单位,一个C语言源程序往往由一个或多个函数组成,但是任何一个C语言源程序有且仅有一个main函数,程序执行从main函数开始,在main函数中结束程序。,函数的分类,库函数自定义函数,库函数prg6-1.c,#include#includevoidmain()inta,s;a=-100;s=abs(a);printf(数据%d的绝对值是%dn,a,s);,(1)标准库函数:函数的功能由系统提供,可以直接调用。(2)调用标准库函数,必须在程序中用编译预处理命令把相应的头文件包含到程序中。(3)头文件位于程序开始处。,引例,#includevoidmain()intx,y,sum,maxdata,i;printf(从键盘输入变量x和y的值n);scanf(%d,%d,分析程序的功能:(1)输出20个*(2)计算两数之和(3)找出两数之间的大值,自定义函数,用户根据实际需求先定义函数,然后通过调用执行函数,实现函数的功能。运算类函数:为了完成某类运算,函数执行结束后会得到运算结果,通常需要将这个结果反馈给调用它的函数。操作类函数:为了完成某类操作,函数的执行过程对应一系列操作,这类函数通常不需要产生反馈结果。,函数的定义,/函数首部函数类型函数名(参数列表)/大括号内的称为“函数体”变量定义语句;操作语句;return语句;,函数的定义,函数首部函数体intmax(inta,intb)intm;if(ab)m=a;elsem=b;returnm;,函数首部,函数类型函数名(参数列表)对于计算类函数,函数执行结束后将向调用它的函数产生一个结果,这个结果的类型就是函数类型,对于操作类函数,函数类型通常定义为void。函数名由用户自己定义,其命名规则和变量名相同。参数是指函数调用时需要提供的初始数据,各参数之间用逗号分隔。参数列表的形式为:参数1类型参数1名,参数2类型参数2名,.,参数n类型参数n名如果函数调用时不需要提供初始数据,则圆括号内的参数可以为空,但是括号不能省略,这样的函数称为无参函数,反之则为有参函数。,intmax(inta,intb)intm;if(ab)m=a;elsem=b;returnm;,函数体,函数体由大括号括起来,用于实现函数功能的若干条语句均写在函数体内。计算类函数需要向调用它的函数产生一个反馈结果,这个结果称为函数返回值,函数体内需要有return语句。函数返回值类型和函数类型应该一致,不一致时以函数类型为准。,intmax(inta,intb)intm;if(ab)m=a;elsem=b;returnm;,程序的执行prg6-2.c,#includevoidmain()intx=3,y=5,z;intmax(inta,intb);z=max(x,y);printf(最大数是:%dn,z);intmax(inta,intb)intm;if(ab)m=a;elsem=b;returnm;,主调函数:发出调用请求的函数。被调用函数:接受调用请求的函数。(1)程序的执行是从主函数main开始的。(2)遇到调用语句时,暂停主函数main的执行,转去执行被调用的自定义函数max。(3)函数发生调用时,参数a和b被分别赋值为3和5。(4)执行函数,变量m中存放的是变量a和b中的最大值5,使用return语句将其反馈给调用它的主函数main。(5)被调用函数执行结束后,返回至主函数继续执行,程序在主函数main中结束。,函数的参数,参数的类型参数的传递,参数的类型,#includevoidmain()/主调函数intx=3,y=5,z;intmax(inta,intb);z=max(x,y);/调用语句printf(最大数是:%dn,z);/被调用的自定义函数maxintmax(inta,intb)intm;if(ab)m=a;elsem=b;returnm;,(1)实际参数:主调函数中调用语句括号内出现的参数,简称实参。/x和y是实际参数(2)形式参数:被调用函数中函数定义时括号内出现的参数,简称形参。/a和b是形式参数,参数的传递,函数调用时,实际参数按照位置上的对应关系依次传递给形式参数。值传递地址传递参数的传递为右结合性。,值传递prg6-3.c,#includevoidmain()/主调函数intx=2,y=3;voidswap(inta,intb);swap(x,y);/调用语句/被调用的自定义函数swapvoidswap(inta,intb)inttemp;if(ab)temp=a;a=b;b=temp;,将实参的数据值单向传递给对应的形参,但是形参的改变不会影响对应的实参。(1)主函数开始执行时,给实际参数分配存储空存储变量值。(2)函数调用时,给形式参数分配空间,实际参数传值给对应的形式参数。(3)实际参数和形式参数占用不同的存储空间。,函数的调用,函数声明嵌套调用递归调用,函数声明,#includevoidmain()/主调函数intx=3,y=2;/函数声明voidswap(inta,intb);swap(x,y);/调用语句/被调用的自定义函数swapvoidswap(inta,intb)inttemp;if(ab)m=a;elsem=b;returnm;,n=max(x,max(y,z);,递归调用prg6-6.c,编程计算n!,其中n从键盘输入。,#includevoidmain()inti,n;longresult=1;printf(从键盘输入变量n的值n);scanf(%d,如果要求设计自定义函数计算n!,程序该如何编写呢?,递归调用prg6-6.c,编程计算n!,其中n从键盘输入。分析n!的数学表达式(1)当n等于0或1时,n!=1(2)当n大于等于2时,n!=n*(n-1)*(n-2)*2*1表达式1事实上,(n-1)!=(n-1)*(n-2)*2*1表达式2合并表达式1和表达式2,可以得到下面的表达式3(3)n!=n*(n-1)!如果定义函数f(n)=n!,那么n!也可以表示为f(n)=n*f(n-1),递归调用prg6-6.c,定义函数f(n)计算n!,/直接递归/函数在本函数体内直接调用本函数longf(intn)longfac;if(n=0|n=1)fac=1;elsefac=n*f(n-1);/*调用f(n)计算n!的过程中又调用了函数f(n-1)*/returnfac;,递归调用,函数在执行过程中对自己的调用,称为函数的递归调用。直接递归:函数在本函数体内直接调用本函数,称为直接递归。间接递归:函数调用其它函数,其他函数又调用本函数,称为间接递归。递归调用的两个条件要解决的问题可以分解成一个新问题,这个新问题的解法与原问题的解决方案相同,不同的只是数据值的变化,也就是调用时传递给形参的数据值有所不同。必须有一个结束条件,在满足结束条件时递归结束。,变量的作用域与生存期,变量的作用域,变量有效的范围称为变量的作用域。(1)局部变量(2)全局变量,局部变量,在某一范围内定义的变量,其作用域仅限于定义它的范围内。说明:局部变量只能在定义它的范围内有效,超出该范围使用即会语法报错。不同函数里面的局部变量可以同名,因为局部变量只在定义它的函数内有效。,全局变量,定义在函数之外的变量,它的作用域是从定义处开始,到所在文件结束。说明:一个C文件中的全局变量和局部变量可以同名,但是在局部变量有效的范围内同名的全局变量被屏蔽。,变量的作用域prg6-7.c,#includeintx1=2,y1=3;/定义全局变量voidmain()intx2=5,y2=7;/定义函数局部变量ints1,s2,s3;s1=x1+y1;s2=x2+y2;intx3=7,y3=9;/定义复合语句局部变量s3=x3+y3;printf(全局变量求和:%dn,s1);printf(函数局部求和:%dn,s2);printf(复合语句局部变量求和:%dn,s3);,外部变量的使用prg6-8.c,如果想在一个C源程序的所有文件中使用全局变量,需要用extern将其声明为外部变量,语法格式为:extern全局变量类型全局变量名;,变量的生存期,动态变量:变量在使用时才分配存储空间,使用完毕立即释放。静态变量:变量在定义时即分配存储空间直至整个程序结束。静态变量需要用关键字static声明,定义静态变量的形式为:static变量类型变量名;说明:静态局部变量作用域仅在定义它的函数内有效,但是它的生存期为整个程序。静态局部变量若未赋初值,系统自动赋值0。函数第一次调用时给静态局部变量赋初值,函数调用结束,静态局部变量的存储空间不会被释放。,变量的生存期prg6-9.c,编程计算15的阶乘并输出计算结果。,#includeintfac(intn);/函数声明voidmain()inti,result;for(i=1;i=5;i+)result=fac(i);printf(%d!=%dn,i,result);,intfac(intn)staticintf=1;f=f*n;returnf;,编译预处理,编译预处理,含义:预处理是指在进行词法扫描和语法分析之前所作的工作。预处理是C语言的一个重要功能,它由预处理程序负责完成。预处理命令是“#”开头的行。一般都放在源程序文件的开头,被称为预处理部分。,宏定义,宏定义是用一个标识符来表示一个字符串,这个标识符称为宏名,定义形式为:#define宏名(参数)字符串无参宏定义有参宏定义说明宏定义不是语句,在行末不加分号。宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束,使用#undef命令可以终止宏定义的作用域。宏名一般用大写字母表示,以便与变量区别。,宏定义prg6-10.c,#include#definePI3.14#defineM3#defineNM*M#defineL(r)r*r#defineS(x)x+2voidmain()floatarea;floats(floatradus);area=s(M);printf(圆面积是:%.2fn,area);floats(floatradus)floatresult;result=PI*L(radus);returnresult;,/无参宏定义,/有参宏定义,文件包含,文件包含命令行的一般形式:#include文件名#include说明:#include文件名和#include的区别使用尖括号表示在包含文件目录中查找,而不在源文件目录中查找。使用双引号表示首先在当前的源文件目录中查找,若未找到才到包含目录中查找。一个include命令只能指定一个被包含文件,若有多个文件要包含,则需要多个include命令。,条件编译,含义:按照不同的条件编译不同的程序部分,即按照条件选择源程序中的不同语句参加编译,产生不同的目标文件。思考:条件编译对程序的执行过程有怎样的影响?,形式1,#ifdef标识符程序段1#else程序段2#endif功能:如果标识符已被#define命令定义,对程序段1进行编译;否则对程序段2进行编译。,条件编译prg6-11.c,#include#definePI3.14#defineS1voidmain()if(R)floatarea;area=PI*R*R;printf(“面积为:%.2fn”,area);elsefloatc;c=2*PI*R;printf(“周长为:%.2fn,c);,#ifdefSfloatarea;area=PI*5*5;printf(“面积为:%.2fn”,area);#elsefloatc;c=2*PI*R;printf(“周长为:%.2fn,c);#endif,形式2,#ifndef标识符程序段1#else程序段2#endif功能:如果标识符未被#define命令定义,对程序段1进行编译;否则对程序段2进行编译。,形式3,#if常量表达式程序段1#else程序段2#endif功能:如果常量表达式的值为非0,对程序段1进行编译;否则对程序段2进行编译。,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


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

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


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