- 函数就是功能,每一个函数用来实现一个特定的功能。在设计一个较大的程序时,往往把它分成若干个程序模块,每一个模块包含一个或多个函数,每一个函数实现一个特定的功能。用函数实现模块化程序设计便于分别编写、分别编译,提高调试效率。
- 一个C程序可由一个主函数和若干个其他函数构成。由主函数调用其他函数,其他函数也可以相互调用(但不能调用main函数)。同一个函数可以被一个或多个函数调用任意多次。
- 一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译的。
- 所有函数都是平行的,即在定义函数时是分别进行的,是相互独立的。一个函数并不从属于另一个函数,即函数不能嵌套定义(但可以相互调用)。
- 在程序中用到的所有函数,必须“先定义,后使用”。
定义函数应包括:
- 函数的名字。(应反映其代表的功能)
- 函数的类型。(即函数值的类型)
- 函数的参数的名字和类型。(无参函数不需要这项)
- 函数应当完成什么操作。(即函数的功能)
从用户使用的角度来看,函数有两种:
- 库函数 :它是由编译系统提供的,用户不必自己定义而可以直接使用它们(如:sqrt、fabs、sin、cos),但此时需要在本文件模块的开头写上:#include<math.h>
- 用户自定义函数:是用户根据实际需求自己设计的,用来实现用户指定的还能。
从函数的形式来看,函数分为两类:
- 无参函数 :一般用来执行一组单纯的操作,在调用无参函数时,主调函数和调用函数之间不发生传递的数据。
定义无参函数的一般形式为:
类型名 函数名()
{
函数体
}
例:
void print_message() //定义print_message
{
printf("Today is Saturday");
}
//函数为void类型,表示不需要带回返回值
- 函数体包括声明部分和执行语句部分。在定义函数时要用“类型名”指定函数值的类型,即函数带回来的值的类型。
- 声明部分包括对函数中用到的变量进行定义以及对将要在本函数中调用的函数进行声明等。
- 对函数的“定义”和“声明”不是一回事。
- 函数的定义是指对函数功能的确立,包括指定函数的名字,函数值类型、形参的类型以及函数体等,它是一个完整的、独立的函数单位
- “声明” 的作用则是把函数的名字、函数值类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致)。!它不包含函数体。
- 有参函数:在调用函数时,主调函数在调用被调函数时,通过参数向被调函数传递。一般情况下,执行被调函数时会得到一个函数值,供主调函数使用。
无参函数的调用形式为:函数名()
例:print_message();
定义有参函数的一般形式为:
类型名 函数名(形式参数表列)
{
函数体
}
例:
int max(int x,int y)
{
int z; //函数体中的声明部分
z=x>y ? x : y;
return (z);
}
- return(z)的作用是将z的值作为函数的值带回到主掉函数中,它又称为函数返回值。return后面的返回值两侧的圆括号可以省写,可简化为“return z;”。
有参函数的调用形式为:函数名(实参表列)
例:max(a,b);
- 如果实参表列包含多个实参,则各参数间用逗号隔开。
- 实参与形参的个数应相等,类型应匹配。
- 实参与形参按顺序对应,向形参传递数据。
- 在定义函数时函数名后面括号中的变量名称为形式参数(形参);在主调函数中调用一个函数时,函数名后面括号中的参数(可以是一个表达式)称为实际参数(实参)。
- 在定义函数中指定的形参,在未出现函数调用时,它们并不占用内存中的存储单元。在发生函数调用时,函数中的形参被分配内存单元。
- 调用结束,形参被释放。!实参单元仍保留并维持原值,没有改变。如果在执行一个被调用函数时,形参的值发生改变,不会改变主调函数的实参的值。
- C语言中,实参向形参的数据传递是“值传递”,单向传递,只有实参传给形参,而不能由形参传回来给实参。
例:输入4个整数,找出其中最大的数(用函数实现)
#include <stdio.h>
int main()
{
int max_4(int a, int b, int c, int d); //max_4函数的声明
int a, b, c, d, max;
printf("Please enter 4 integer numbers:");
scanf("%d %d %d %d",&a,&b,&c,&d);
max = max_4(a, b, c, d); //调用max_4函数,得到4个数的最大者,赋给变量max
printf("max=%d \n",max);
return 0;
}
int max_4(int a, int b, int c, int d) //定义max_4函数
{
int max(int x, int y); //max函数的声明
int m;
m = max(a,b); //调用max函数,找出a,b中的最大者
m= max(m, b); //调用max函数,找出a,b,c中的最大者
m= max(m, d); //调用max函数,找出a,b,c,d中的最大者
return m; //函数返回值是个数中的最大者
}
int max(int x, int y) //定义max函数
{
return(x > y ? x : y); //函数返回值是x,y中的最大者
}
- 从程序中可以看到对函数的声明与函数定义中的函数首部基本上是相同的。因此可以简单地照写已定义的函数的首部,再加一个分号,就成为 了对函数的“声明”。在函数声明中也可以不写形参名,而只写形参的类型。 在C语言中,函数声明称为函数原型(function prototype)。使用函数原型是ANSI C的一个重要特点。它的作用主要是利用它在程序的编译阶段对调用函数的合法性进行全面检查。
- 递推方法求 n ! n! n!
#include <stdio.h>
int main()
{
long fac(int n); //对fac函数进行声明
int n;
long fact; //变量fact用来存放n!的值
printf("Please enter a integer number: \n"); //输出一行信息,请用户输入n
scanf("%d", &n); //输入n
if (n < 0) //当输入为负值时,判为数据异常
printf("n<0,data error!");
else //当n为0或整数时,调用函数
{
fact = fac(n);
printf("%d!=%ld\n",n,fact); //输出n!
}
return 0;
}
long fac(int n) //定义fac函数
{
int i;
long fac = 1;
for (i = 1; i <= n; i++) //计算n!
fac *= i;
return fac; //将结果返回
}
- 递归方法求 n ! n! n!
#include <stdio.h>
int main()
{
long fac(int n);
int n;
long fact;
printf("Please enter a interger number: \n");
scanf("%d", &n);
if (n < 0)
printf("n<0,data error!");
else
{
fact = fac(n);
printf("%d!=%ld\n",n,fact);
}
return 0;
}
long fac(int n)
{
long fact;
if (n == 0 || n == 1) //0!和1!等于1
fact = 1;
else
fact = n*fac(n-1); //递归调用fac函数
return fact;
}