函数在C语言是实现特定功能的一系列语句。当程序代码达到一定规模之后,如果所有的功能还使用一个main函数中完成,那么必将会出现代码的冗余和功能划分不清晰等问题,极其不利于项目的管理。函数本身可以是独立的功能,将相关的语句“汇集”到一起完成特定的功能,如果用户在多个地方都需要使用这个功能,那么直接调用这个已经现成的代码就可以了,这样的好处是:1.不需要将同一份代码复制到不同的地方,这样可以减少错误的发生;2.复用了已有开发成果,提高开发效率。本文将从函数的定义开始介绍函数的基本用法。

如何自己定义一个函数呢?首先明确下函数的构成要素,定义一个函数需要以下4个要素:

  1. 函数的名称
  2. 函数的参数
  3. 函数体
  4. 函数的返回值

我们以下面的代码为例,说明下函数的各个构成要素

图1

图1定义了一个名称为sum的函数,它含有一个类型为int的参数,其返回值类型也为int,函数体实现了从0-n的数值相加,最后将这个相加的结果作为返回值。代码第10行指定了函数的名称为sum,函数名称与其它的标识符命名规则相同。函数的参数个数可以根据实际需求指定,本例中只使用了一个参数,对应图1中代码第10行,类型为int型,名称为n。函数体位于第10-17行花括号内,其内的语句实现了这个函数的功能,经过代码第11-14行运算后,第16行代码将运算的结果使用return关键字返回,即这个函数运行完成之后会像其它的表达式一样生成一个数值,这个数值的类型就是由函数的返回值类型所决定,本例中第10行代码中的最左侧的关键字int指明了这个函数的返回值类型为一个整型数值。

函数的4个要素在一些场景下可以进行“退化”或者说是说省略,比如,有的函数可以不使用参数(或称为使用void型参数),有的函数可以返回值(也可以说是使用void型返回值),比如下面的代码定义了一个显示菜单功能的函数,它既没有参数也没有返回值,在函数体中只是输出一些内容至屏幕上的语句。

图2

图2中的函数定义中,参数列表(圆括号中的内容为空)也可以使用一个关键字void表示,就像返回值类型一样,参数列表中的void关键字是可以省略的。但是对于函数的返回值类型void来说,它是必须存在的,一定不可以省略。

函数中的参数列表的功能是什么?函数一个很重要的特性就是封装了一些功能,但这些功能并非完全独立工作,想要这些功能正常地运行,它需要“外界”提供给这个函数一些信息,这些信息就是通过函数列表来进行“通信”,函数获得这些信息之后会根据这些信息计算出的对应的结果。就像图1中定义的函数sum一样,如果我们提供给这个函数的参数为3,那么这个函数运行后的返回值就是6,而如果提供给这个函数的参数为5,那么这个函数的返回值变为了15。这个参数就像是输入的内容,函数的返回值就像是输出的内容,函数本身就像一个执行运算的盒子。

函数体是整个函数的中心,它具体负责实现这个函数的功能,函数体定义了一系列的语句,或者是进行赋值,或者是进行判断,或者是进行数学运算等待,这所有的操作就是为了完成这个函数所有实现的功能,比如图1中的函数中的每一行代码都是为了计算这n+1个数字之和而服务的。在函数体中,我们可以定义一些变量,构造一些表达式,也可以使用条件语句,循环语句等,当然也可以调用函数。需要注意的是函数的参数对于函数体来说可以认为是定义在函数体最前面的变量,这些变量的值被初始化为用户调用这个函数时所指定的数值了,这些参数在函数的整个执行期间都是可以使用的。

函数的调用。如果只是定义了一个函数,那么这个函数是不会自动执行的,需要通过语句来调用这个函数,比如定义了图1中的函数,使用下图3中的方法调回用这个函数。

图3

函数sum既包含参数列表,又有一个整型的返回值,那么我们在调用这个函数的时候,就可以指定这个函数的名称sum和参数10来执行这个函数,但是调用函数的时候需要将调用者传递参数(称为实参,函数定义中的参数称为形参)放置到圆括号内,如:sum(10);就可以完成函数的调用了,需要注意的是,对于sum这个函数而言,它是含有返回值的,如果调用这个函数时只是让其计算n+1个数值的和,而不去存储这个数值其实没有实际作用,返回值就是将运算后的结果交给调用者的数值,就像图3中第32行代码所示,通过一个赋值语句将sum(10)函数的返回值作为total变量的初始值,这个total的值就存放了0-10所有数字之和。

函数不仅仅是做一些数学计算,它还可以进行一些数据查找、排序或分析等操作,下面的代码,我们定义一个数据查找功能的函数,名称设置为find;形式参数(形参)设置为3个,第一个参数类型为int型,为待查找的数值,名称为n,第二个参数为int型数组,为存放int数值的数组名称,第三个参数为第二个参数数组大小,类型为int型;函数的返回值为一个int型,表示待查找的数值位于数组中的下标位置,-1表示在数组中没有找到对应的数值。

图4

图4代码定义了一个find函数,函数体主要代码是一个for语句,它从数组的索引0开始,依次访问数组中的每一个元素,通过数组中的元素与第一个参数n进行比较,如果二者相同,那么就返回这个元素所对应的下标值,如果在整个数组中没有找到对应的数值,那么,代码执行到第26行代码,将返回数值-1。

这个函数定义,使用了三个参数,其中第二个参数为一个数组类型,它的写法与数组的定义不同,数组定义时要么提供数组元素个数,要么提供初始化数组的值列表。而函数参数中的数组类型只需要提供方括号即可表示这是一个数组,它的大小是通过另外一个参数额外指定。

这个函数的调用方式和图1中sum函数的调用方式相类似,只是二者的参数类型和个数有所区别,在测试代码中我们首先创建了两个变量,一个是待查找的数值v变量,另外一个是整型数组,数组初始化时设置一些整型数,之后调用find函数进行查找数值40是否存在于数组之中,如下:

图5

函数调用的第三个参数,我们使用了数组大小操作符sizeof,它给出了数组a中整型数字的个数,这三个参数都按照find参数的要求传入了正确的实参,调用这个函数之后,其返回值7就赋值到int型变量index中,这样就完成了函数的调用。