首页 > 编程笔记

C语言函数调用(2种方式)

C 程序总是从主函数 main() 开始执行,到 main() 函数结束为止。在函数体的执行过程中,不断地对函数进行调用来实现一些子功能,调用者称为主调函数,被调用者称为被调函数。被调函数执行结束,从被调函数结束的位置再返回主调函数调用的位置,继续执行主调函数后面的语句。

如下图所示,是一个函数调用的简单例子。

C语言函数调用方式

函数调用的一般形式有以下两种。

1) 函数语句

当C语言中的函数只进行了某些操作而不返回结果时,使用这种形式,该形式作为一条独立的语句,例如:

函数名(实参列表);/*调用有参函数,实参列表中有多个参数,中间用逗号隔开*/

或者:

函数名();/*调用无参函数*/

如“swap(x,y);”就是这种形式,要求函数仅完成一定的操作,比如输入、输出、排序等。

注意:函数后面有一个分号“;”。还有像printf()、scanf()等函数的调用也属于这种形式。例如:printf("%d",p);

2)函数表达式

当所调用的函数有返回值时,函数的调用可以作为表达式中的运算分量,参与一定的运算。例如:

m=max(a,b);        /*将max()函数的返回值赋给变量m*/
m=3*max(a,b);        /*将max()函数的返回值乘以3赋给变量m*/
printf("Max is %d",max(a,b));         /*输出也是一种运算,输出max()函数的返回值*/

一般 void 类型的函数使用函数语句的形式,因为 void 类型没有返回值。对于其他类型的函数,在调用时一般采用函数表达式的形式。

【示例1】编写一个函数,求任意两个整数的最小公倍数。
#include<stdio.h>
int sct(int m,int n)  /*定义sct()函数求最小公倍数*/    
{
   int temp,a,b;
   if (m<n)     /*如果m<n,交换m,n的值,使m中存放较大的值*/
   {
      temp=m;
      m=n;
      n=temp;
   }
   a=m; 
   b=n;           /*保存m,n原来的数值*/
   while(b!=0)      /*使用辗转相除法求两个数的最大公约数*/
   {
      temp=a%b;
      a=b;
      b=temp;
   }
   return(m*n/a); /*返回两个数的最小公倍数,即两数相乘的积除以最大公约数*/
}
int main()
{  
   int x,y,g;
   printf("请输入两个整数:");     
   scanf("%d%d",&x,&y);
   g=sct(x,y);                    /*调用sct()函数*/
   printf("最小公倍数为:%d\n",g); /*输出最小公倍数*/
}
运行结果:

请输入两个整数:24 16
最小公倍数为:48

示例中调用了 sct() 函数,该函数有两个参数,因此在调用时实参列表也有两个参数,且与这两个参数的个数、类型、位置是一一对应的。sct() 函数有返回值,因此在主调函数中,函数的调用参与一定的运算,这里参与了赋值运算,将函数的返回值赋给了变量 g。

C语言函数的声明

我们在学习变量时,要求遵循“先定义后使用”的原则,同样,在调用函数时也要遵循这个原则。也就是说,被调函数必须存在,而且在调用这个函数之前,一定要给出这个函数的定义,这样才能成功调用。

如果被调函数的定义出现在主调函数之后,这时应给出函数的原型说明,以满足“先定义后使用”的原则。

函数声明的目的是使编译系统在编译阶段对函数的调用进行合法性检查,判断形参与实参的类型及个数是否匹配。

函数声明采用函数原型的方法。函数原型就是函数定义的首部。

有参函数的声明形式为:

函数类型函数名(形参列表);

无参函数的声明形式为:

函数类型函数名();


注意:函数声明包含函数的首部和一个分号“;”,函数体不用写。

有参函数声明时的形参列表只需要把一个个参数类型给出就可以了,可以省略变量名,例如:

int power(int,int);

函数声明可以放在所有函数的前面,如果放在主调函数内,需在调用被调函数之前声明。

【示例2】编写一个函数,求半径为 r 的球的体积。球的半径 r 由用户输入。代码如下:
#include<stdio.h>
double volume(double);    /*函数的声明*/
int main()
{  
   double r,v;
   printf("请输入半径:");   
   scanf("%lf",&r);
   v=volume(r);
   printf("体积为:%lf\n\n",v);
}
double volume(double x)
{
   double y;
   y=4.0/3*3.14*x*x*x;
   return y;
}
运行结果:

请输入半径:3
体积为:113.040000


示例中被调函数 volume() 的定义在调用函数之后,需要在调用该函数之前给出函数的声明,声明的格式只需要在函数定义的首部加上分号,且声明中的形参列表只需要给出参数的类型即可,参数名字可写可不写,假如有多个参数则用隔开。

函数的声明在下面 3 种情况下是可以省略的。

注意:如果被调函数是C语言提供的库函数,调用时不需要作函数声明,但必须把该库函数的头文件用 #include 命令包含在源程序的最前面。

例如,getchar()、putchar()、gets()、puts() 等,这样的函数定义是放在 stdio.h 头文件中的,只要在程序的最前面加上 #include<stdio.h> 就可以了。 同样,如果使用数学库中的函数,则应该用 #include<math.h>。

C语言函数的嵌套调用

在C语言中,函数之间的关系是平行的、独立的,也就是在函数定义时不能嵌套定义,即一个函数的定义函数体内不能包含另外一个函数的完整定义。但是C语言允许嵌套调用,也就是说,在调用一个函数的过程中可以调用另外一个函数。

【示例3】函数嵌套调用示例。代码如下:
#include<stdio.h>
fun2(int x,int y)
{
   int z;
   z=2*x-y;
   return z;
}
fun1(int x,int y)
{
   int z;
   z=fun2(x,x+y);      /*在fun1()函数内调用fun2()函数*/
   return z;
}
main()
{
   int a,b,c;
   printf("请输入两个整数:");
   scanf("%d%d",&a,&b);
   c=fun1(a,b);         /*调用fun1()函数*/
   printf("%d\n",c);
}
运行结果:

请输入两个整数:5 8
-3


代码中有两层的嵌套,其执行过程是:
  1. 执行 main() 函数的函数体部分;
  2. 遇到函数调用语句,程序转去执行 fun1() 函数;
  3. 执行 fun1() 函数的函数体部分;
  4. 遇到函数调用 fun2() 函数,转去执行 fun2() 函数的函数体;
  5. 执行 fun2() 函数体部分,直到结束;
  6. 返回 fun1() 函数调用 fun2() 处;
  7. 继续向下执行 fun1() 函数的尚未执行的部分,直到 fun1() 函数结束;
  8. 返回 main() 函数调用 fun1() 处;
  9. 继续向下执行 main() 函数的剩余部分,直到结束。

优秀文章