2.7 函数
C语言的程序是由一个个函数构成的,除了有且必须有的main主函数以外,用户也可以自己定义函数。此外,C语言的编译系统还提供了一些库函数。函数为程序的封装提供了一种简便的方法,在其他地方使用函数时不需要考虑它是如何实现的。在使用正确设计的函数时不需要考虑“它是怎么做的”,只需要知道“它是做什么的”就够了。当定义好一个函数后,我们可以通过函数调用的方式来使用该函数的功能。
在上述示例中,所使用的函数(如cos、printf与scanf等)都是函数库所提供的。接下来看看怎样编写自己的函数。我们通过编写一个求阶乘的函数factorial(int n)来说明定义函数的方法。
factorial(int n)函数用于计算整数n的阶乘,比如factorial(4)的值为24。这个函数不是一个实用的阶乘函数,它只能用于处理比较小的整数的阶乘,因为如果要求阶乘的整数比较大,那么使用该方法很容易越界,导致程序无法获得正确的结果。希望读者读完整本书以后,能为该问题找到正确的解决方法。
下面给出函数factorial(int n)的定义及调用它的主程序,由此可以看到引入函数后的整个程序结构,如例2-7所示。
例2-7 计算整数0~9的阶乘。
#include <stdio.h>
int factorial(int n); /声明factorial函数 /
int main()
{
int i;
for (i = 0; i < 10; ++i)
printf("%d的阶乘是:%d\n", i, factorial(i)); / 调用factorial函数计算i的阶乘 /
return 0;
}
/ factorial:n的阶乘,n >= 0 /
int factorial(int n)
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i)
p = p * i;
return p;
}
函数定义的一般形式为:
返回值类型 函数名(可能有的参数定义)
{
声明和定义序列
语句序列
}
不同函数的定义可以按照任意次序出现在一个源文件或多个源文件中,但同一函数不能分开存放在几个文件中。如果源程序出现在几个文件中,那么对它的编译和装入将比整个源程序放在同一文件时要做的声明更多,但这是操作系统的任务,而不是语言属性。我们暂且假定两个函数放在同一文件中,从而使前面所学的有关运行C程序的知识在目前仍然有用。
在上述示例中,factorial函数定义的第一行int factorial(int n)声明了参数的类型与名字以及该函数返回的结果的类型。factorial的参数名只能在factorial内部使用,在其他函数中不可见,因此在其他函数中可以使用与之相同的参数名而不会发生冲突。一般而言,把在函数定义中用圆括号括起来的变量称为形式参数。
factorial函数计算得到的值由return语句返回给main函数。关键词return后可以跟任何表达式:
return 表达式;
函数不一定都返回一个值。不含表达式的return语句用于使程序执行流程返回调用者(但不返回有用的值)。调用函数也可以忽略(不用)一个函数所返回的值。读者可能已经注意到,在main函数末尾也有一个return语句。由于main本身也是一个函数,它也可以向其调用者返回一个值,这个调用者实际上就是程序的执行环境。一般而言,返回值为0表示正常返回,返回值非0则表示引发异常或错误终止条件。
对函数的使用称为函数调用。main主函数在如下程序语句中对factorial函数进行了调用:printf("%d的阶乘是:%d\n", i, factorial(i));
调用factorial函数时,传送了一个变量i给它。一般把函数调用中与参数对应的值或变量称为实际参数,如变量i,由实际参数传递值给形式参数。factorial函数则在调用执行完时返回一个整数。在表达式中,factorial(i)就像i一样是一个整数。