资源描述
第6章 函数第1页 在这一章中将介绍在这一章中将介绍C语言程序函数,函数语言程序函数,函数是一段连续程序代码组合,它用来完成一定功是一段连续程序代码组合,它用来完成一定功效,一个效,一个C语言程序往往由很多个函数组成,语言程序往往由很多个函数组成,函数之间并列排放,相互调用,协同工作,完函数之间并列排放,相互调用,协同工作,完成一个大任务。成一个大任务。第2页6.1函数定义函数定义6.2函数参数与返回值数函数参数与返回值数6.3变量类型变量类型6.4函数调用函数调用第3页6.1函数定义函数定义实实际际上上读读者者对对函函数数并并不不陌陌生生,C语语言言中中有有大大量量内内部部函函数数,程程序序主主体体main就就是是一一个个函函数数,除除此此之外在程序中还能够定义自己函数。之外在程序中还能够定义自己函数。返返回回类类型型函函数数名名称称(类类型型1参参数数1,类类型型2参参数数2,)/函数体函数体返返回回类类型型是是函函数数值值数数据据类类型型,能能够够是是C语语言言中中char、int、short、long、float、double等等任任何何一一个个基基本本数数据据类类型型。返返回回类类型型能能够够省省略略不不写写,如如不写则默认为不写则默认为int类型。类型。第4页函函数数名名称称是是用用户户自自己己定定义义名名称称,与与变变量量命命名名规则一样。规则一样。函函数数能能够够有有很很多多参参数数,每每一一个个参参数数都都有有一一个个类类型型及及名名称称,它它们们是是函函数数变变量量,不不一一样样变变量量对对应应函函数数值值往往往往不不一一样样,这这是是函函数数本本质质所所在在,这这些些参参数称为函数形式参数。数称为函数形式参数。函函数数体体是是函函数数程程序序代代码码,它它们们包包含含在在一一对对大大括号内。括号内。函函数数被被设设计计成成为为完完成成某某一一个个功功效效一一段段程程序序代代码码或或模模块块,C语语言言把把一一个个问问题题划划分分成成多多个个模模块块,分分别别对对应应一一个个个个函函数数,一一个个C语语言言程程序序往往往往有有多多个个函函数数组组成成,最最简简单单C语语言言程程序序只只有有一一个个函函数数,那那就就是是main函数自己。函数自己。第5页6.2函数参数与返回值数函数参数与返回值数6.2.1函数参数在在调调用用函函数数时时,形形式式参参数数要要求求了了函函数数需需要要数数据据个个数数及及其其类类型型,实实际际参参数数必必须须在在类类型型与与数数目上与形式参数一样,普通规则是:目上与形式参数一样,普通规则是:(1)形形式式参参数数是是函函数数内内部部变变量量,有有名名称称及及类类型型。形形参参出出现现在在函函数数定定义义中中,在在整整个个函函数数体体内内都能够使用,离开该函数则不能使用;都能够使用,离开该函数则不能使用;(2)实实际际参参数数个个数数与与类类型型必必须须与与形形式式参参数数一一致致,实实际际参参数数能能够够是是变变量量,常常数数、表表示示式式、甚甚至是一个函数;至是一个函数;第6页(3)当当实实际际参参数数是是变变量量时时,它它不不一一定定要要与与形形式式参参数数同同名名称称,实实际际参参数数变变量量与与形形式式参参数数变变量量是是不不一一样样内内存存变变量量,它它们们其其中中一一个个值值改改变变不不会会影响到另外一个变量。影响到另外一个变量。(4)如如实实际际参参数数类类型型与与形形式式参参数数类类型型不不完完全全一一致致,最最少少是是能能够够赋赋值值转转换换,不不然然会会发发生生“类类型不匹配型不匹配”错误;错误;第7页(5)函函数数调调用用中中发发生生数数据据传传送送是是单单向向,即即只只能能把把实实参参值值传传送送给给形形参参,而而不不能能把把形形参参值值反反向向地地传传送送给给实实参参,所所以以在在函函数数调调用用过过程程中中,形形参参值发生改变,而实参中值不会改变;值发生改变,而实参中值不会改变;(6)函函数数能能够够没没有有参参数数,但但此此时时圆圆括括号号不不可可缺乏;缺乏;第8页6.2.2函数返回值 函函数数值值是是指指函函数数被被调调用用之之后后,执执行行函函数数体体中中程程序序段段所所取取得得并并返返回回给给主主调调函函数数值值。普普通通函函数数计计算算后后总总有有一一个个返返回回值值,经经过过函函数数内内部部return语句来实现这个返回值,格式是:语句来实现这个返回值,格式是:return表示式;表示式;return返返回回一一个个数数据据类类型型与与函函数数返返回回类类型型一一致致表示式,该表示式值就是函数返回值。表示式,该表示式值就是函数返回值。第9页6.2.3没有返回值函数1没有返回值函数没有返回值函数函函数数也也能能够够没没有有返返回回值值,这这种种函函数数返返回回类类型被定义成型被定义成void类型,类型,例以下面函数:例以下面函数:voidSayHello()puts(“Hello,everyone!”);void类类型型函函数数中中也也能能够够有有return语语句句,但但return后后面面不不能能够够有有任任何何表示式,比如:表示式,比如:voidfun(floatx)if(x0)return;/在在xy?x:y);则则调调用用Max函函数数后后值值不不确确定定,比比如如Max(1,2)值值不不一定是。一定是。第11页6.2.4函数调用函函数数调调用用是是比比较较简简单单,调调用用自自己己编编写写函函数数就就象象调调用用C语语言言内内部部函函数数一一样样。有有返返回回值值函函数数能能够够放放在在适适当当任任何何一一个个表表示示式式中中去去计计算算,当当然然也也能能够够单单独独作作为为一一条条语语句句执执行行。而而void类类型型函函数数不不能能用用在在任任何何一一个个表表示示式式中中去去参参加加计计算算,只只能能作作为为单单独独一一条条语语句句执执行。行。但但C语语言言中中要要求求,函函数数必必须须先先定定义义才才能能够够调调用用,既既在在调调用用函函数数时时编编译译器器必必须须已已经经事事先先知知道道该该函函数数参参数结构,不然编译会犯错误。数结构,不然编译会犯错误。第12页 对对库库函函数数调调用用不不需需要要再再作作说说明明,但但必必须须把把该该函函数数头头文文件件用用include命命令令包包含含在在源源文文件件前前部部,实实际上际上include命令包含头文件中就是库函数说明。命令包含头文件中就是库函数说明。main函函数数是是C语语言言中中主主函函数数,程程序序是是从从main函函数数第第一一条条语语句句开开始始,当当main最最终终一一条条语语句句执执行行完完成成后后,main函函数数执执行行完完成成,这这么么整整个个程程序序就就执执行行完完成成。一一个个复复杂杂C程程序序中中main函函数数要要去去调调用用别别函函数数,而而被被main调调用用函函数数又又有有可可能能再再去去调调用用别别函函数数,这么形成函数层层调用,从而完成一个复杂任务。这么形成函数层层调用,从而完成一个复杂任务。第13页6.3变量类型变量类型6.3.1局部变量局部变量 局局部部变变量量也也称称为为内内部部变变量量。局局部部变变量量是是在在函函数数内内作作定定义义说说明明。其其作作用用域域仅仅限限于于函函数数内内,离开该函数后再使用这种变量是非法。离开该函数后再使用这种变量是非法。第14页关于局部变量作用域还要说明以下几点:关于局部变量作用域还要说明以下几点:(1)函函数数中中定定义义变变量量只只能能在在函函数数中中使使用用,不不能能在在其其它它函函数数中中使使用用。同同时时,一一个个函函数数中中也也不不能能使使用用其其它它函函数数中中定定义义变变量量。各各个个函函数数之之间间是是平平行行关关系系,每每个个函函数数都都封封装装了了一一块块字字节节区区域域,互互不相干。不相干。(2)形形参参变变量量是是属属于于被被调调函函数数局局部部变变量量,实实参参变量是属于主调函数局部变量。变量是属于主调函数局部变量。(3)允允许许在在不不一一样样函函数数中中使使用用相相同同变变量量名名,它它们们代代表表不不一一样样对对象象,分分配配不不一一样样单单元元,互互不不干干扰扰,也也不不会会发发生生混混同同。例例6_3中中sum函函数数m、s变变量量与与main函函数数m、s变变量量同同名名,但但它它们们是是不不一样变量。一样变量。第15页6.3.2全局变量局变量1全局变量作用域全局变量作用域全全局局变变量量也也称称为为外外部部变变量量,它它是是在在函函数数外外部部定定义义变变量量。它它不不属属于于哪哪一一个个函函数数,它它属属于于一一个个源源程程序序文文件件。其其作作用用域域是是整整个个源源程程序序。全全局局变变量量普普通通在在程程序序开开头头部部分分定定义义,任任何何一一个个函函数数都都能能够够使使用用它它,当当在在一一个个函函数数中中改改变变了了全全局局变变量量值值时时,会会直接影响到其它函数访问值。直接影响到其它函数访问值。全全局局变变量量也也能能够够在在程程序序别别位位置置定定义义,只只要要它它在在函函数数之之外外就就行行,但但在在使使用用它它时时必必须须让让编编译译器器已已经经知知道道它它是是什什么么,所所以以也也像像函函数数说说明明那那样样,在在程程序序使使用用它它之之前前必必须须先先说说名名变变量量,说说明明方方法法是是用用extern申明变量。申明变量。第16页2全局变量与局部变量全局变量与局部变量前前面面已已经经讲讲到到全全局局变变量量作作用用域域是是整整个个程程序序,它它在在程程序序开开始始时时就就存存在在,任任何何函函数数都都能能够够访访问问它它,而而且且全全部部函函数数访访问问同同名名称称全全局局变变量量是是同同一一个变量,全局变量只有在程序结束时才销毁。个变量,全局变量只有在程序结束时才销毁。局局部部变变量量是是函函数数内内部部范范围围内内变变量量,当当执执行行此此函函数数时时才才有有效效,退退出出函函数数后后局局部部变变量量就就销销毁毁。不不一一样样函函数数之之间间局局部部变变量量是是不不一一样样,哪哪怕怕同同名名字也互不相干。字也互不相干。第17页但但存存在在一一个个问问题题,就就是是假假如如一一个个函函数数内内部部局局部部变变量量与与程程序序全全局局变变量量同同名名字字,那那么么函函数数访访问问到到变变量量是是函函数数自自己己局局部部变变量量呢呢还还程程序序全全局局变变量量?这这种情况下种情况下C语言要求局部变量优先。语言要求局部变量优先。局局部部变变量量有有局局部部性性,这这使使得得函函数数有有对对立立性性,函函数数与与外外界界接接口口只只有有函函数数参参数数与与它它返返回回值值,使使程程序序模模块块化化更更突突出出,这这么么有有利利于于开开发发大大型型程程序序。全全局局变变量量含含有有全全局局性性,是是实实现现函函数数之之间间数数据据交交换换公公共共路路径径,但但大大量量地地使使用用全全局局变变量量会会破破坏坏函函数数独独立立性性,造造成成程程序序模模块块化化程程度度下下降降,所所以以要要尽尽可可能能降降低低使使用用全全局局变变量量,多多使使用用局局部部变变量量,函函数数之之间间应应尽尽可可能能保保持持其其独独立立性性,函函数数之之间间最最好好只只经经过过接接口口参数来传递数据。参数来传递数据。第18页6.3.3静态变量变量静静态态变变量量是是一一个个在在变变量量定定义义时时就就分分配配存存放放单单元元并并一一直直保保持持不不变变变变量量,直直至至整整个个程程序序结结束束。静静态态变变量量用用static来来定定义义,静静态态变变量量也也称称为为static变变量量,没没有有用用static定定义义变变量量就就称称为为是是动动态变量或普通变量。态变量或普通变量。静静态态变变量量也也能能够够分分全全局局静静态态变变量量与与局局部部静静态态变变量量变变量量。全全局局static变变量量与与全全局局普普通通变变量量在在只只有有一一个个源源程程序序系系统统中中没没有有什什么么区区分分,只只有有在在多个源程序文件系统中才有区分。多个源程序文件系统中才有区分。第19页6.3.4变量初始值变量初始值C语语言言对对于于普普通通函函数数内内部部局局部部变变量量、静静态态变变量量以以及及全全局局变变量量初初始始值值设设置置是是不不一一样样。对对于于普普通通函函数数内内部部局局部部变变量量假假如如在在定定义义时时没没有有设设置置它它初初始始值值,则则变变量量值值是是随随机机,但但对对于于静静态态变变量量或或全全局局变变量量,假假如如在在定定义义时时没没有有设设置置它它初初始始值值则则变量值是变量值是0。在在程程序序设设计计中中要要确确保保变变量量初初始始化化,尤尤其其是是对局部变量初始化,不然会得到预想不到结果。对局部变量初始化,不然会得到预想不到结果。第20页6.4函数调用函数调用6.4.1嵌套调用在在C语语言言中中,全全部部函函数数定定义义,包包含含主主函函数数main在在内内,都都是是平平行行。函函数数之之间间允允许许相相互互调调用用,也也允允许许嵌嵌套套调调用用。习习惯惯上上把把调调用用者者称称为为主主调调函函数数。main函函数数是是全全程程序序主主函函数数,它它能能够够调调用用其其它它函函数数,而而不不允允许许被被其其它它函函数数调调用用。C程程序序执执行行总总是是从从main函函数数开开始始,完完成成对对其其它它函函数数调调用用后后再再返返回回到到main函函数数,最最终终由由main函函数数结结束束整个程序。整个程序。第21页嵌嵌套套调调用用就就是是一一个个函函数数调调用用另另外外一一个个函函数数,被被调调用用函函数数又又深深入入调调用用另另外外一一个个函函数数,形形成成一一层层层层嵌嵌套套关关系系,一一个个复复杂杂程程序序存存在在多多层层函函数数调调用用。如如图图6-10所所表表示示展展示示了了这这种种关关系系,main函函数数调调用用函函数数A,在在A中中又又调调用用函函数数B,B又又调调用用C,在在C完完成成后后返返回回B调调用用处处,继继续续B执执行行,之之后后B执执行行完完成成返返回回A调调用用处处,A又又接接着着往往下下执执行行,随随即即A又又调调用用D函函数数,D执执行行完完后后返返回回A,A执执行行完完后后返返回回main函函数数,main接接着着往往下下执执行行,main完成后程序就结束了。完成后程序就结束了。第22页图6-10函数嵌套调用第23页对应程序结构以下:对应程序结构以下:voidD()voidC()voidB()C();voidA()B();D();voidmain()A();第24页函函数数调调用用能能够够这这么么一一层层层层地地嵌嵌套套下下去去,但但函函数数调调用用普普通通不不能能够够出出现现循循环环,如如图图6-11所所表表示示是是一一个个循循环环,函函数数X调调用用函函数数Y,Y又又反反过过来来调调用用X,之之后后X又又调调用用Y,没没完完没没了了,形形成死循环。成死循环。第25页图6-11函数循环第26页6.4.2递归调用上面讲到函数普通不能形成循环调用,但上面讲到函数普通不能形成循环调用,但函数能够自己调用自己,既自己形成循环调用,函数能够自己调用自己,既自己形成循环调用,这种自己调用自己调用称为递归。递归调用实这种自己调用自己调用称为递归。递归调用实际上是一个循环,这种调用关键是要设置好循际上是一个循环,这种调用关键是要设置好循环条件,让循环进行到一定程度时能一层层地环条件,让循环进行到一定程度时能一层层地退出,不能形成死循环,所以这一类程序编写退出,不能形成死循环,所以这一类程序编写要格外小心。要格外小心。第27页
展开阅读全文