首页 > 编程笔记

C语言函数定义及其格式说明(非常详细)

作为 C 程序的基本组成部分来说,函数是具有相对独立性的程序模块,能够供其他程序调用,并在执行完自己的功能后,返回调用它的函数中。函数的定义实际上就是描述一个函数所完成功能的具体过程。

函数定义的一般形式如下。

函数类型 函数名(类型说明 变量名,类型说明变量名,…)
{
     函数体
}

示例1

定义求最大值的函数。代码如下:
#include<stdio.h>
int max(int a,int b)  /*定义函数max()*/
{
   int c;
   c=a>b?a:b;     /*求a,b两个数的最大值,赋给c*/
   return c;     /*将最大值返回*/
}
int main()
{
   int x,y;
   printf("请输入两个整数:");
   scanf("%d%d",&x,&y);
   printf("%d和%d的最大值为:%d\n",x,y,max(x,y));
}
运行结果:

请输入两个整数:8 6
8和6的最大值为:8

本示例中的 max() 函数是一个求 a、b 两者中的最大值的函数。

a、b 是形式参数,当主调函数 main() 调用 max() 函数时,把实际参数 x、y 的值传递给被调用函数中的形参 a 和 b。max 后面括号中的 “int a,int b” 对形参作类型说明,定义 a 和 b 为整型。花括号括起来的部分是函数体,作用是计算出a、b的最大值并赋值给c,通过 return 语句将 c 的值返回到主调函数中。

示例中 max() 函数的说明如下。

1) 函数名必须符合标识符的命名规则(即只能由字母、数字和下划线组成,开头只能为字母或下划线),且同一个程序中函数不能重名,函数名用来唯一标识一个函数。

看到函数名时,建议读者能够见名知意。如函数名为 max,一看就知道是求解最大值的。

2) 函数类型规定了函数返回值的类型。如 max() 函数是 int 型。函数的返回值也是 int 型,函数的返回值变量 c 的类型是 int 型。也就是说函数值的类型和函数的类型应该是一致的,它可以是 C 语言中任何一种合法的数据类型。若函数类型与返回值类型不一致,系统会把返回值类型自动转换成函数类型返回。

如果函数不需要返回值(即无返回值函数),则必须用关键字 void 加以说明。

默认的返回值类型是 int 型。例如:

double max(int a,int b)    /*函数返回值类型为double型*/
void max(int a,int b)      /*函数无返回值*/
max(int a,int b)          /*函数返回值类型不写,表示默认为int型*/


3) 函数名后面圆括号括起来的部分称为形式参数列表(即形参列表),方括号括起来的部分是可选的。如果有多个形式参数,应该分别给出各形式参数的类型,并用逗号隔开,该类函数称为有参函数。例如:

int max(int a,int b,float c)    /*有参函数,有3个形参a、b、c,中间用逗号隔开,每个参数分别说明类型*/

如果形参列表为空,则称为无参函数。无参函数的定义形式为:

类型说明 函数名()
{
  函数体
}

例如:

int max()/*无参函数*/

注意:函数名后面圆括号的形参列表可以为空(即可以没有参数),但圆括号一定要有。有参函数与无参函数的唯一区别就是括号里面有没有形参,其他都是一样的。

4) 函数体是由一对花括号“{}”括起来的语句序列,用于描述函数所要进行的操作。函数体包含了说明部分和执行部分。其中,说明部分对函数体内部所用到的各种变量类型进行定义和声明,对被调用的函数进行声明;执行部分是实现函数功能的语句序列。

如【示例1】中“int c;”是函数体的说明部分,执行部分很简单,只有后面两句。

注意:函数体一定要用花括号括起来,例如主函数的函数体也是用花括号括起来的。

5) 还有一类比较特殊的函数是空函数,即函数体内没有语句。调用空函数时,空函数表示什么都不做。例如:

void empty()
{
}

使用空函数的目的仅仅是“占位置”。因为在程序设计中,往往会根据需要确定若干个模块,分别由一个函数来实现,而在设计阶段,需要一个一个模块(函数)设计、调试,在编写程序时,可以在将来准备扩充功能的地方写上一个空函数,占一个位置,以后逐一设计函数代码代替空函数。利用空函数占位,对于复杂程序的编写、调试及功能扩充非常有用。

6) C程序中所有的子函数都是平行的,不属于任何其他函数,它们之间可以相互调用。但是函数的定义不能包含在另一个函数的定义内,即函数定义不能嵌套。

下面这种函数定义的形式是不正确的:

int func_fst(int a,int b)   /*第1个函数的定义*/
{
   ...
   int func_snd(int c,int d)    /*第2个函数的定义*/
   {
   ...
   }
   ...
}

如果中间 func_snd() 函数的功能相对独立,就把它放在 func_fst() 函数的外面进行定义,而在 func_fst() 函数中可以对它进行调用,例如:

int func_fst(int a,int b)    /*第1个函数的定义*/
{
   ...
   func_snd(m,n);      /*对第2个函数的调用*/
   ...
}
int func_snd(int c,int d)   /*第2个函数的定义*/
{
    ...
}

如果 func_snd() 函数不具备独立性,与上下文联系密切,就不需要再设置一个函数,而直接将代码嵌入第 1 个函数的定义中,作为其中的一部分即可。

7) 在函数定义中,可以包含对其他函数的调用,后者又可以调用另外的函数,甚至自己调用自己,即递归调用。但子函数不能调用主函数,主函数可以调用任意子函数。

优秀文章