已阅读5页,还剩58页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2020/5/20,1,第7章函数与变量作用域,C语言是通过函数来实现模块化程序设计的。教学目的:掌握函数的定义与调用,变量的作用域;了解函数的嵌套与递归调用,内部、外部函数特点,以及变量的存储特性。,2020/5/20,2,教学内容:7.1*函数的定义与调用7.2函数的嵌套调用与递归调用7.3内部函数与外部函数7.4*内部变量与外部变量7.5变量的存储特性本章要点本章作业与上机实践,2020/5/20,3,7.1*函数定义与函数调用,7.1.1函数定义任何函数都是由函数说明和函数体两部分组成。1分类根据函数有无参数,将函数分为无参函数和有参函数。,2020/5/20,4,(1)无参函数函数类型函数名(void)说明语句部分;可执行语句部分;(2)有参函数函数类型函数名(数据类型参数,数据类型参数2)说明语句部分;可执行语句部分;,形参表。调用有参函数时,由调用函数为形参提供实际值,简称为实参。,在新标准中,函数不可缺省参数表;用“void”表示不需要参数。,2020/5/20,5,2函数的返回值与函数类型语言的函数,还可分为有返回值函数和无返回值函数两种。(1)有返回值函数与return语句一般格式:return(返回值表达式);功能:返回调用函数,并将“返回值表达式”的值带给调用函数。注意:函数中无return语句,返回1个不确定的值。可用“void”定义成“无(空)类型”,明确表示不返回值。,括号可以缺省,2020/5/20,6,(2)函数类型函数类型应与return语句中“返回值表达式”的类型一致。如果不一致,则以函数类型为准。如果缺省函数类型,则系统一律按int型处理。良好的程序设计习惯:为了使程序具有良好的可读性并减少出错,将无返回值函数定义为空类型void;同时,也不使用系统对函数类型的缺省处理。,2020/5/20,7,案例7.1定义一个求两个整数中极大值的max()函数。/*功能:求2个整数中的较大数*/*形参:2个,整型*/*返回值:2个整数中的较大数*/intmax(intn1,intn2)/*函数定义*/return(n1n2?n1:n2);/*/voidmain(void)intmax(intn1,intn2);/*对被调用函数进行说明*/intnum1,num2;printf(inputtwonumbers:);scanf(%d%d,2020/5/20,12,显然,对于被多个函数调用的自定义函数而言,采用预先统一说明方式进行说明,可以有效地减少函数说明次数。注意:如果被调用函数的定义体,出现在调用函数之前,可以缺省说明。,2020/5/20,13,2、函数调用函数名(实参表)例如,在案例7.1的主函数中:printf(,max(num1,num2);注意:调用有参函数,必须提供实参(常量/变量/表达式/函数)。调用时,实参必须具有确定的值,且与形参个数相等、类型匹配。,2020/5/20,14,(1)调用方式语句方式无返回值函数的调用,可作为一条独立的语句。例如,printf()、scanf()等库函数的调用,均作为一条独立的语句。表达式方式有返回值函数作为表达式的一项,以函数返回值参与表达式的运算。例如,“max=max(x,y)”是一个赋值表达式,把max()函数的返回值赋予变量max。,2020/5/20,15,(2)断点与函数调用的返回断点被调用函数执行完毕,返回调用函数后继续执行的位置。调用函数中的断点位置分两种情况:语句调用方式:断点为函数调用语句的下一条语句。例如,案例7.1中的语句调用“printf();”,其断点为该语句的下一条语句“getch();”。,2020/5/20,16,表达式调用方式:断点为函数调用所在的表达式。例如,在案例7.1中,“printf(,max(num1,num2);”语句中的表达式调用“max(num1,num2)”:其断点为该表达式调用所在的表达式“max(num1,num2)”(在本例中,“max(num1,num2)”函数调用既是表达式调用,本身又构成一个简单表达式)。,2020/5/20,17,7.1.3参数传递发生函数调用时,根据参数值的性质不同,将参数传递分为两种:(1)值传递参数值是一个一般数据(整形、实型、字符型数据等)。系统把实参值复制1份给形参;被调用函数结束时,形参值不能传回给实参。(2)地址(引用)传递参数值是一个地址。,2020/5/20,18,执行案例7.1时的参数传递:intmax(intn1,intn2)return(n1n2?n1:n2);main()intmax(intn1,intn2);intnum1,num2;printf(inputtwonumbers:);scanf(%d%d,/*调用函数sum()*/voidsum(intnum)sum+=factor(loop);/*求累计和*/longfactor(intnum)/*求num的阶乘*/,2020/5/20,24,在案例7.3中,主函数main()调用求和函数sum(),sum()又循环调用求阶乘的函数factor()。一般地说,函数的嵌套调用是指,在执行被调用函数时,该函数又调用其它函数的情形。注意:被调用函数执行完毕后,将返回到调用函数的断点继续执行。简言之,谁调用,返回到谁的断点继续执行。,2020/5/20,25,7.2.2函数的递归调用案例7.4用递归法计算n!(1!=1,n!=(n-1)!*n(n2))。算法设计要点:(1)根据计算n!的递归定义可知,为了计算n!,必须首先计算(n-1)!;以此类推,直至1!(1!=1)。(2)依据1!求2!=1!*2,再依据2!求3!=2!*3;同理,依据(n-1)!求n!=(n-1)!*n。,2020/5/20,26,longfactor(intnum)longfact;if(num1)fact=factor(num1)*num;elsefact=1;return(fact);以num=5为例,其执行过程详见教材7.2.2。,递归调用自己,2020/5/20,27,语言允许函数直接(或间接)地调用它自己,称为递归调用;这种函数称为递归函数。例如,案例7.4中的函数factor()就是一个递归函数。防止递归调用无终止地进行的常用办法:添加1个继续(或终止)递归调用的条件判断。例如,案例7.4中函数factor()中的“if(num1)”。返回,2020/5/20,28,7.3内部函数和外部函数,C语言程序中的函数,是通过被调用而执行的,所以一个函数需要被其它函数调用。但是,当一个程序由多个源文件组成时,在一个源文件中定义的函数,能否被其它源文件中的函数调用呢?语言据此将函数分为内部函数和外部函数。,2020/5/20,29,7.3.1内部函数(又称静态函数)如果在一个源文件中定义的函数,只能被本源文件中的其它函数调用,这种函数称为内部函数。1定义static函数类型函数名(形参表)2特点:只能被本文件中的函数所调用。3好处:不用担心与其它源文件中的函数同名,因为即使同名也没关系。,2020/5/20,30,7.3.2外部函数如果在某源文件中定义的函数,可被同一程序中所有源文件中的函数调用,这种函数称为外部函数。1定义:extern函数类型函数名(形参表)2特点:允许被所有源文件中的函数所调用。3调用其它源文件中的外部函数时,需要对其进行说明:extern函数类型函数名(形参表),函数名2(形参表2);,2020/5/20,31,案例7.5将加、减、乘、除和求余数运算练习程序(第3版)的源文件组织形式改为:实现加、减、乘、除和求余数运算的程序段,均作为1个独立的函数、存储在1个独立的源文件中。程序框架如下(完整程序详见案例源代码):,2020/5/20,32,/*外部函数说明*/externvoidaddition(intn1,intn2);externvoidsubtraction(intn1,intn2);externvoidmultiplication(intn1,intn2);externvoiddivision(intn1,intn2);externvoidremainder(intn1,intn2);voidmain(),2020/5/20,33,7.3.3多个源文件的编译和连接在软件工程项目中,采用结构化方法进行程序设计与编程,通常会产生多个源文件(例如源程序文件、数据结构定义文件等)。那么,如何将这些源文件编译、连接成一个统一的可执行文件呢?一般有两种方法:,2020/5/20,34,(1)分别编译、一并连接C编译程序是以源文件为编译单位。当一个程序中的函数和数据结构分放在多个源文件中时:先将各文件分别编译,再通过link命令产生一个可执行文件(.exe)。(2)集中编译、连接利用编译预处理命令#include,将其它源文件包含到主函数main()所在的源文件的开头;然后直接编译该文件即可。,2020/5/20,35,例如,在案例7.5中的主函数main()所在的源文件case75_1.c的开头添加如下几行:/*将其它各源文件包含进来*/#includecase75_2.c#includecase75_3.c#includecase75_4.c#includecase75_5.c#includecase75_6.cvoidmain()返回,2020/5/20,36,7.4*内部变量与外部变量,语言中的变量,定义位置不同,其作用域也不同,据此将变量分为内部变量和外部变量。7.4.1内部变量1、内部变量在函数内(函数说明+函数体)定义的变量。2、作用域只在该函数范围内有效。所以内部变量也称“局部变量”。,2020/5/20,37,例如,在案例7.4中,主函数main()中定义的变量num就是内部变量,它仅在主函数main()中才能使用;求阶乘的factor()函数,函数说明中的形参变量num,以及函数体中定义的变量fact,均属内部变量,都只能在factor()函数中使用。说明:在不同的函数中,允许使用同名内部变量。它们代表不同的对象,互不干扰。例如,在案例7.4中,主函数main()中的内部变量num,与函数factor()中的内部变量num同名。,2020/5/20,38,案例内部变量的应用。voidmain()voidsum(intnum);intnum=100;printf(“num_main()=%dn”,num);/*调用前实参的值*/sum(num);/*调用函数*/printf(num_main()=%dn,num);/*调用后实参的值*/getch();voidsum(intnum)inti;printf(num_sum()=%dn,num);/*改变前的形参值*/for(i=num-1;i=1;i-)num+=i;/*改变形参的值*/printf(num_sum()=%dn,num);/*改变后的形参值*/,2020/5/20,39,7.4.2外部变量1、外部变量在函数外部定义的变量。2、作用域:从外部变量的定义位置开始,到本文件结束为止。外部变量不从属于任何一个函数,可被作用域内的所有函数使用,所以外部变量又称全局变量。,2020/5/20,40,案例7.6设计一个函数cuboid(intlength,intwidth,intheight)(3个参数依次为长方体的长、宽、高),用于求长方体的体积及正、侧、顶三个面的面积。算法设计要点:函数cuboid(intlength,intwidth,intheight)本身只能返回1个值(本案例选定体积),正、侧、顶三个面的面积就只能通过外部变量来进行数据共享。参考程序框架如下:,2020/5/20,41,longarea1,area2,area3;/*定义3个外部变量,用于数据共享*/longcuboid(intlength,intwidth,intheight);/*函数说明*/voidmain()volume=cuboid(length,width,height);printf(nvolume=%ld,area1=%ld,area2=%ld,area3=%ld,volume,area1,area2,area3);,2020/5/20,42,longcuboid(intlength,intwidth,intheight)longvolume;volume=length*width*height;/*计算体积*/area1=length*width;/*计算3个面的面积*/area2=width*height;area3=length*height;return(volume);/*返回体积值*/,2020/5/20,43,3、说明(1)外部变量的作用域:从定义点到本文件结束。为方便使用,建议:将外部变量的定义放在文件开头,如案例7.6所示。(2)在同一源文件中,允许外部变量和内部变量同名。在内部变量的作用域内,外部变量不起作用。,2020/5/20,44,(3)外部变量可实现函数之间的数据共享,但又使这些函数依赖这些外部变量,因而使得这些函数的独立性降低。注:从模块化程序设计观点来看,这是不利的。因此不是非用不可时,不要使用外部变量。,2020/5/20,45,案例内部、外部变量的同名应用。intlen=3,width=4,high=5;intvs(intlen,intwidth)intvol;vol=len*width*high;/*引用外部变量high*/returnv;main()intlen=5;printf(len=%d,width=%d,high=%d,vol=%d,len,width,high,vs(len,width);,len=?width=?,len=?,2020/5/20,46,7.4.3小结1内部变量在函数内(函数说明+函数体)定义的变量,其作用域:只在该函数范围内有效。不同函数中的同名内部变量,互不干扰。2外部变量在函数外部定义的变量,其作用域:从外部变量的定义位置开始,到本文件结束为止。允许内部、外部变量同名。在内部变量的作用域内,外部变量不起作用。返回,2020/5/20,47,7.5变量的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 3.1《网络改变世界》课件 2026-2027学年度道德与法治八年级上册 统编版
- 《信息技术(MS Office+AI拓展)》教案全套 张娇
- 合规转利润:降本增效全指南(2026)《GBT 39302-2020再生水水质 阴离子表面活性剂的测定 亚甲蓝分光光度法》
- 彩钢板屋面翻新防水施工方案
- 2026年浙江省人教版初中数学第3章函数综合应用模拟试卷
- 2026年浙江省高中数学选修2-2第6章数列习题
- 《汽车营销》-第一章教学用
- 合规转利润:降本增效全指南(2026)《GBT 39046-2020政务服务平台基础数据规范》
- 护理基础学:冷疗和热疗
- 高血钾症的诊断与治疗
- 县委办安保工作方案
- 八年级生物下册生物的遗传教学教案苏科版(2025-2026学年)
- 雨课堂学堂在线学堂云《工程伦理与学术道德(电科大)》单元测试考核答案
- 2025年人教版三年级道德与法治上册全册教学设计
- 工程机械设备租赁服务方案投标文件(技术方案)
- 挖掘机设备检验报告模板及填写指南
- 代谢相关脂肪性肝病基层诊疗与管理指南解读 3
- 头部内伤病课件
- 2025年人教版高一语文开学摸底考试(适合全国一卷地区含解析)
- 医院医保对账管理制度
- T/CEPPEA 5028-2023陆上风力发电机组预应力预制混凝土塔筒施工与质量验收规范
评论
0/150
提交评论