第七章 函数

 

一、二、三、四、五、六、七、...



由于采用了函数模块式的结构,C语言易于实现结构化程序设计。使程序的层次结构清晰,便于程序的编写、阅读、调试。

一、 函数的概念

应用计算机求解复杂的实际问题,总是把一个任务按功能分成若干个子任务,每个子任务还可再细分。一个子任务称为一个功能块,用函数实现。应用这种策略组织程序,主函数 main 和其它函数构成程序的层次结构。

在C 语言中,函数是模块化程序设计的唯一工具。模块化程序设计是基于函数的逐步求精法。

这一方法的思路是:在抽象程序的逐步细化过程中,将操作看成函数调用,最终得到一个层次分明的程序结构。应用这种方法设计出的程序,结构清晰、易读、易理解、易调试、易维护;适合开发大任务、多人员设计,也便于软件管理。划分模块,要求函数功能单一,规模适中;对函数功能、函数名、函数形参表和函数返回值类型都必须作出明确规定和说明;要绘出程序层次结构图。在开发程序过程中,首先是设计和调试程序总体框架,然后,逐步扩大设计和调试其它功能模块。

在C语言中可从不同的角度对函数分类。

1.  从函数定义的角度看,函数可分为库函数和用户定义函数两种。

1)   库函数:由C系统提供,用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用。在前面各章的例题中反复用到printf、scanf、getchar、putchar、gets、puts、strcat等函数均属此类。

2)   用户定义函数:由用户按需要写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。

2.  C语言的函数兼有其它语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。

1)   有返回值函数:此类函数被调用执行完后将向调用者返回一个执行结果,称为函数返回值。如数学函数即属于此类函数。由用户定义的这种要返回函数值的函数,必须在函数定义和函数说明中明确返回值的类型。

2)   无返回值函数:此类函数用于完成某项特定的处理任务,执行完成后不向调用者返回函数值。这类函数类似于其它语言的过程。由于函数无须返回值,用户在定义此类函数时可指定它的返回为“空类型”,空类型的说明符为“void”。

3.  从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。

1)   无参函数:函数定义、函数说明及函数调用中均不带参数。主调函数和被调函数之间不进行参数传送。此类函数通常用来完成一组指定的功能,可以返回或不返回函数值。

2)   有参函数:也称为带参函数。在函数定义及函数说明时都有参数,称为形式参数(简称为形参)。在函数调用时也必须给出参数,称为实际参数(简称为实参)。进行函数调用时,主调函数将把实参的值传送给形参,供被调函数使用。

4.  C语言提供了极为丰富的库函数,这些库函数又可从功能角度作以下分类。

1)   字符类型分类函数:用于对字符按ASCII码分类:字母,数字,控制字符,分隔符,大小写字母等。

2)   转换函数:用于字符或字符串的转换;在字符量和各类数字量(整型,实型等)之间进行转换;在大、小写之间进行转换。

3)   目录路径函数:用于文件目录和路径操作。

4)   诊断函数:用于内部错误检测。

5)   图形函数:用于屏幕管理和各种图形功能。

6)   输入输出函数:用于完成输入输出功能。

7)   接口函数:用于与DOS,BIOS和硬件的接口。

8)   字符串函数:用于字符串操作和处理。

9)   内存管理函数:用于内存管理。

10)  数学函数:用于数学函数计算。

11)  日期和时间函数:用于日期,时间转换操作。

12)  进程控制函数:用于进程管理和控制。

13)  其它函数:用于其它各种功能。

二、 函数定义的一般形式

1.  无参函数的定义形式

   类型标识符 函数名()

       {声明部分

        语句

       }

其中类型标识符和函数名称为函数头。类型标识符指明了本函数的类型,函数的类型实际上是函数返回值的类型。该类型标识符与前面介绍的各种说明符相同。函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少。

{ }中的内容称为函数体。在函数体中声明部分,是对函数体内部所用到的变量的类型说明。在很多情况下都不要求无参函数有返回值,此时函数类型符可以写为void。

2.  有参函数定义的一般形式

   类型标识符 函数名(形式参数表列)

       { 声明部分

        语句

      }

有参函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数,它们可以是各种类型的变量,各参数之间用逗号间隔。在进行函数调用时,主调函数将赋予这些形式参数实际的值。形参既然是变量,必须在形参表中给出形参的类型说明。

三、调用函数

1.函数调用的一般形式为:

函数名(实参表列)

如果是调用无参函数,则“实参表列”可以没有,但括号不能省略。如果实参表列包含多个实参,则各参数间用逗号隔开。

2.  函数调用的方式

在C语言中,可以用以下几种方式调用函数:

1.  函数表达式:函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数是有返回值的。例如:z=max(x,y)是一个赋值表达式,把max的返回值赋予变量z。

2.  函数语句:函数调用的一般形式加上分号即构成函数语句。例如:    printf("%d",a);scanf ("%d",&b);都是以函数语句的方式调用函数。

3. 函数实参:函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的。例如:    printf("%d",max(x,y));    即是把max调用的返回值又作为printf函数的实参来使用的。在函数调用中还应该注意的一个问题是求值顺序的问题。所谓求值顺序是指对实参表中各量是自左至右使用呢,还是自右至左使用。

四、函数的参数和函数的值

1.函数的参数

函数的参数分为形参和实参两种。形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。实参出现在主调函数中,进入被调函数后,实参变量也不能使用。形参和实参的功能是作数据传送。发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。

函数的形参和实参具有以下特点:

1.   形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。

2.   实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。

3.   实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配”的错误。

4.   函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

2.函数的返回值

函数的返回值是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值。

1)   函数的值只能通过return语句返回主调函数。

return  语句的一般形式为:

return 表达式;

或者为:

return (表达式);

该语句的功能是计算表达式的值,并返回给主调函数。在函数中允许有多个return语句,但每次调用只能有一个return 语句被执行,因此只能返回一个函数值。

2)   函数值的类型和函数定义中函数的类型应保持一致。如果两者不一致,则以函数类型为准,自动进行类型转换。

3)   如函数值为整型,在函数定义时可以省去类型说明。

4)   不返回函数值的函数,可以明确定义为“空类型”,类型说明符为“void”

为了使程序有良好的可读性并减少出错, 凡不要求返回值的函数都应定义为空类型。

五、函数的嵌套调用

C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用。即在被调函数中又调用其它函数。

例:计算s=22!+32!

本题可编写两个函数,一个是用来计算平方值的函数f1,另一个是用来计算阶乘值的函数f2。主函数先调f1计算出平方值,再在f1中以平方值为实参,调用 f2计算其阶乘值,然后返回f1,再返回主函数,在循环程序中计算累加和。

long f1(int p)

{

int k;

long r;

long f2(int);

k=p*p;

r=f2(k);

return r;

}

long f2(int q)

{

long c=1;

int i;

for(i=1;i


    关注 DatabaseTime


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册