c语言函数的调用过程

我在b站也有看一些C语言入门视频,对函数的调用过程也是有了一些了解:

所谓函数调用(Function Call),就是使用已经定义好的函数。函数调用的一般形式为:

函数名(实参列表);

实参可以是常数、变量、表达式等,多个实参用逗号,分隔。

在C语言中,函数调用的方式有多种,例如:

 
  1. //函数作为表达式中的一项出现在表达式中
  2. z = max(x, y);
  3. m = n + max(x, y);
  4. //函数作为一个单独的语句
  5. printf("%d", a);
  6. scanf("%d", &b);
  7. //函数作为调用另一个函数时的实参
  8. printf( "%d", max(x, y) );
  9. total( max(x, y), min(m, n) );

在函数调用中还应该注意的一个问题是求值顺序。所谓求值顺序是指对实参列表中各个参数是自左向右使用呢,还是自右向左使用。对此,不同编译器的规则可能不同。请看下面一段代码:

 
  1. #include <stdio.h>
  2. int main(){
  3. int i=8;
  4. printf("%d %d %d %d\n",++i,++i,--i,--i);
  5. return 0;
  6. }

在 VC6.0 和 C-Free 5.0 下的运行结果为:

8 7 6 7

在 Xcode 下的运行结果为:

9  10  9  8

可见 VC 6.0 和 C-Free 5.0 是按照从右至左的顺序求值,而 Xcode 相反,按照从左向右的顺序求值。

函数的嵌套调用

函数不能嵌套定义,但可以嵌套调用,也就是在一个函数的定义或调用过程中出现对另外一个函数的调用。

【示例】计算sum = 1! + 2! + 3! + ... + (n-1)! + n!

分析:可以编写两个函数,一个用来计算阶乘,一个用来计算累加的和。

 
  1. #include <stdio.h>
  2.  
  3. //求阶乘
  4. long factorial(int n){
  5. int i;
  6. long result=1;
  7. for(i=1; i<=n; i++){
  8. result *= i;
  9. }
  10. return result;
  11. }
  12.  
  13. // 求累加的和
  14. long sum(long n){
  15. int i;
  16. long result = 0;
  17. for(i=1; i<=n; i++){
  18. //嵌套调用
  19. result += factorial(i);
  20. }
  21. return result;
  22. }
  23.  
  24. int main(){
  25. printf("1!+2!+...+9!+10! = %ld\n", sum(10));
  26. return 0;
  27. }

运行结果:
1!+2!+...+9!+10! = 4037913

sum() 的定义中出现了对 factorial() 的调用,printf() 的调用过程中出现了对 sum() 的调用,而 printf() 又被 main() 调用,它们整体调用关系为:

factorial()  -->  sum()  -->  printf()  -->  main()

如果一个函数 A() 在定义或调用过程中出现了对另外一个函数 B() 的调用,那么我们就称 A() 为主调函数或主函数,称 B() 为被调函数。

当主调函数遇到被调函数时,主调函数会暂停,CPU 转而执行被调函数的代码;被调函数执行完毕后再返回主调函数,主调函数根据刚才的状态继续往下执行。

一个C语言程序的执行过程可以认为是多个函数之间的相互调用过程,它们形成了一个或简单或复杂的调用链条。这个链条的起点是 main(),终点也是 main()。当 main() 调用完了所有的函数,它会返回一个值(例如return 0;)来结束自己的生命,从而结束整个程序。

函数是一个可以重复使用的代码块,CPU 会一条一条地挨着执行其中的代码,当遇到函数调用时,CPU 首先要记录下当前代码块中下一条代码的地址(假设地址为 0X1000),然后跳转到另外一个代码块,执行完毕后再回来继续执行 0X1000 处的代码。整个过程相当于 CPU 开了一个小差,暂时放下手中的工作去做点别的事情,做完了再继续刚才的工作。

从上面的分析可以推断出,在所有函数之外进行加减乘除运算、使用 if...else 语句、调用一个函数等都是没有意义的,这些代码位于整个函数调用链条之外,永远都不会被执行到。C语言也禁止出现这种情况,会报语法错误,请看下面的代码:

  1. #include <stdio.h>
  2.  
  3. int a = 10, b = 20, c;
  4. //错误:不能出现加减乘除运算
  5. c = a + b;
  6.  
  7. //错误:不能出现对其他函数的调用
  8. printf("c.biancheng.net");
  9.  
  10. int main(){
  11. return 0;
  12. }

猜你喜欢

转载自blog.csdn.net/guiwukejiBGG/article/details/81606057