程序设计语言(C) 第三章 函数

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

程序设计语言(C)第三章函数[本章重点]C中函数的定义、调用和参数传递;参数传递时的两种调用方式:传值调用和引用调用;函数的重载和递归调用;部分常见系统函数的用法。[本章难点]函数之间进行参数传递时两种调用方式;函数的递归调用;函数重载。函数是C源程序的基本模块,一个C控制台程序一般由一个主函数main()和若干个应用函数组成。主函数main()是整个应用程序的开始执行点,正常情况下,整个C控制台应用程序也是在main()函数中结束的。主函数可以调用应用函数,而应用函数之间也可以根据其逻辑关系相互调用。调用其他函数的函数称为主调函数,而被调用的应用函数称被调函数。我们把实现某种功能的算法编成一个个相对独立的函数模块,然后用调用的方法来使用这些函数。函数的分类C语言系统自身提供了丰富的应用函数,这些函数被称为系统函数。系统函数无需用户定义,只需在源程序前连接包含有该函数原型的头文件,即可在程序中直接调用(在稍后的章节里介绍)。此外,还可以根据需求,把算法编成独立的函数模块,在源程序的适当位置进行定义和调用,这类应用函数叫做用户自定义函数。在C语言源程序中,用户自定义函数应用遵循先定义后使用的原则。函数定义类型标识符函数名(形式参数表){语句}•类型标识符和函数名称为函数头,类型标识符指明了本函数的类型,函数的类型实际上是函数返回值的数据类型,该类型标识符与前面介绍的各种数据类型说明符相同,一些情况下函数也可以没有返回值,此时函数类型标识符应为void。求两个整型数据中较大的整数intmax(intx,inty){if(xy)returnx;elsereturny;}将华氏温度转换为摄氏温度floatftoc(floatf){floatc;c=5*(f-32)/9;returnc;}函数原型声明•在C程序中,一个函数的定义可以放在任意位置,既可放在主调函数之前,也可放在主调函数之后,为了避免由于函数定义位置的不确定性而引起的编译错误,C要求应在应用函数调用之前为其构造原型,即在源程序中首先声明函数原型。•类型标识符函数名(形式参数表);•其中:类型标识符、函数名、形式参数表的规定与函数的定义相同。该语句最后的分号不能缺少。上节2个例题中的函数原型声明分别为:floatftoc(floatf);intmax(intx,inty);注意:1)同一个函数的原型声明与函数定义,在类型标识、函数名称以及形式参数表上必须完全一致。2)函数原型声明必须出现在函数调用之前。3)函数原型声明时,形式参数表中可以不包含参数的名字,只包含参数的类型。因此,函数ftoc原型声明也可写为:floatftoc(floatf);函数的调用•函数被定义以后,只有在主调函数的适当位置对它进行调用,才能发挥其作用。函数调用实际上就是转去执行这段用函数名命名的程序代码,它包括参数传递、执行代码、返回函数值等操作。•调用形式:函数名(实际参数表)•其中:函数调用中的函数名称应与函数定义中的函数名称相一致;实际参数表中给出的实际参数(简称实参),是主调函数转去执行被调函数了时,希望参与被调函数运算的实际值,它们可以是常量、变量或表达式。对函数ftoc的调用floatftoc(floatf);voidmain(){floatx,y;cout请输入华氏温度:;cinx;y=ftoc(x);cout华氏温度x度=摄氏温度y度endl;}函数的返回值•要将被调函数的计算结果,有效的传递到主调函数中去(即返回函数值),采用return语句实现。•return语句的一般格式为:•return表达式;•该语句的功能是终止函数的执行,并向主调函数返回函数值,返回的函数值就是return语句中表达式的值。该语句的表达式可以省略,若省略表达式,return语句仅表示终止函数的执行,并将系统控制权交给主调用函数。使用return语句应注意以下几点•1)有返回值函数的函数体中至少应有一个return语句。•2)C允许函数体中存在多个return语句,当程序流程执行到其中的某个return语句时,终止函数的执行。•3)关键字return后面的表达式可有可无,当return语句不带表达式,又位于函数体的最后时,return语句可以省略。•4)关键字return后面的表达式可以用()括起来,也可以省略括号。•5)函数默认的返回值数据类型为整型。形式参数和实际参数•在调用函数时,大多数情况下,主调函数和被调用函数之间有数据传递关系。这就是前面提到的有参函数。在定义函数时函数名后面括弧中的变量名称为“形式参数”(简称“形参”),在主调函数中调用一个函数时,函数名后面括弧中的参数(可以是一个表达式)称为“实际参数”(简称“实参”)。•形式参数在函数定义时说明,在整个函数体内都可以使用,离开该函数则不能使用,它约定了主调函数在调用该函数时,所要传递给该函数的数据个数和每个要传递数据的类型等。实际参数出现在主调函数中,进入被调函数后,实参变量也不能使用。实际参数就是在调用函数时,主调函数传递给被调函数符合形参约定的实际数据。也就是说,发生函数调用时,主调函数把实参传送给被调函数的形参,从而实现主调函数向被调函数的数据传送。函数形参和实参的特点1.实参可以是常量、变量、表达式、函数等,无论实参是何种类型,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值、输入、计算等办法使实参获得确定值。2.实参和形参在数量、类型和顺序上应严格一致,否则会发生“类型不匹配”的错误。3.一般情况下,形参变量只有在被调用时才分配内存单元,调用结束即刻释放所分配的内存单元。所以,形参只在函数内部有效,函数调用结束返回主调函数后,则不能再使用形参变量。因此,这种情况下函数调用中发生的数据传送是单向的,即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。传值调用voidswap(inta,intb);voidmain(){intx=3,y=5;cout交换前:x=xy=yendl;swap(x,y);cout交换后:x=xy=yendl;}voidswap(inta,intb){cout交换前:a=ab=bendl;inttemp;temp=a;a=b;b=temp;cout交换后:a=ab=bendl;}•程序的运行结果是:•交换前:x=3y=5•交换前:a=3b=5•交换后:a=5b=3•交换后:x=3y=5•swap()函数用于交换两个参数的值,从运行结果可以看出,主函数中变量x、y的值在调用swap()函数时作为实际参数传递给了swap()函数的形式参数a、b,执行swap()函数的结果,确实将函数体内变量a、b里的值进行了交换。但是,由于函数调用采用的是传值调用,形式参数值的改变并不影响实际参数的值,所以,当函数返回时主函数中变量x、y的值没有发生变化。函数的引用调用•与传值调用不同,函数的引用调用将在主调函数的实参变量与被调函数的形参变量之间建立某种联系,使得形参变量的变化将影响实参变量的值。•在使用引用调用时,要在函数定义时将函数的形式参数类型用引用运算符“&”说明为引用类型。所谓引用,简单的说就是另一个目标的别名,对引用的操作就相当于对引用所代表的目标进行的操作。所以,如果在函数之间用引用的方式来传递数据(形参作为实参的引用),那么在被调函数中对形参变量的改变也会影响到实参变量。voidswap(int&a,int&b);voidmain(){intx=3,y=5;cout交换前:x=xy=yendl;swap(x,y);cout交换后:x=xy=yendl;}voidswap(int&a,int&b){cout交换前:a=ab=bendl;inttemp;temp=a;a=b;b=temp;cout交换后:a=ab=bendl;}•交换前:x=3y=5•交换前:a=3b=5•交换后:a=5b=3•交换后:x=5y=3•自定义函数swap(int&a,int&b)采用了引用调用形式,从运行结果可以看出,主函数中变量x、y的值在调用swap()函数时作为实际参数,以引用方式传递给了swap()函数的形式参数a、b,此时,a、b应是变量x、y的别名。执行swap()函数的结果,不仅将函数体内变量a、b里的值进行了交换,当函数返回时主函数中变量x、y的值也发生了相应的改变。对任意从键盘输入的3个数,通过调用函数求它们中的最大数、最小数和平均数floataverage(inta,intb,intc,int&min,int&max);voidmain(){inta,b,c,min=0,max=0;floats;cout请输入3个整数abc:;cinabc;s=average(a,b,c,min,max);cout最大值=max最小值=min平均值=sendl;}floataverage(intx1,intx2,intx3,int&y1,int&y2){floatx;y1=((x1x2)?x1:x2);y1=((y1x3)?y1:x3);y2=((x1x2)?x1:x2);y2=((y2x3)?y2:x3);x=(x1+x2+x3)/3.0;returnx;}•上述程序中自定义函数average(intx1,intx2,intx3,int&y1,int&y2)包含5个形式参数,其中3个传值,两个引用。函数计算x1、x2、x3(即a、b、c)的最大数y1、最小数y2和平均数x,y1、y2是主函数中变量min、max的引用,所以,函数执行过程中对y1、y2的改变直接影响min、max,变量x的值作为函数的返回值,在函数执行结束时带回主函数并由主函数的赋值表达式赋予变量s。当被调函数average()执行结束返回主程序时,min为3个数中最小数、max为3个数中的最大数,s为3个数的平均数。函数的嵌套调用•C语言中不允许在一个函数体内出现对另一个函数的定义,即嵌套的函数定义。因此,各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的函数体中出现对另一个函数的调用,这样就出现了函数的嵌套调用,即在被调函数中又调用其它函数。函数2……返回函数1main函数调用函数1结束main函数…………函数1调用函数2返回main函数…………编程计算,其中计算x2和n!分别由自定义函数pow2和fact实现intpow2(intx,inty);intfact(intn);voidmain(){inta=3,b=5,s;s=pow2(a,b);couts=sendl;}22!5!3sintpow2(intx,inty){intf1,f2;f1=fact(x);f2=fact(y);returnf1*f1+f2*f2;}intfact(intn){inti,f=1;for(i=1;i=n;i++)f*=i;returnf;}•程序运行结果:•s=14436•上述程序中,主函数在执行s=pow2(a,b)语句时遇到函数调用,转去执行函数pow2并将a、b的值3和5传递给pow2函数的形参变量x和y,执行函数pow2的过程中,又有f1=fact(x)和f2=fact(y)两语句要调用fact函数,转去执行fact函数分别得到x!和y!,之后从fact返回pow2函数,pow2函数计算出x!的平方、y!的平方之和,返回这个和到主函数。函数的递归调用•函数不仅可以调用其他函数,也可以自己调用自己,这种函数自己调用自己的过程叫做函数的递归调用。函数的递归调用包括直接的自身调用和间接的自身调用。•递归的过程可分为两个阶段,即“递推”和“回归”。所谓递推是函数自身逐级调用的过程,反映在内存中就是调用函数的信息(包括运行环

1 / 51
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功