您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

从C语言函数调用发现程序运行的秘密

时间:12-26来源:作者:点击数:
所谓函数调用(Function Call),就是使用已经定义好的函数。函数调用的一般形式为:
函数名(实参列表);

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

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

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

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

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

在 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!

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

#include <stdio.h>
//求阶乘
long factorial(int n){
    int i;
    long result=1;
    for(i=1; i<=n; i++){
        result *= i;
    }
    return result;
}
// 求累加的和
long sum(long n){
    int i;
    long result = 0;
    for(i=1; i<=n; i++){
        //嵌套调用
        result += factorial(i);
    }
    return result;
}
int main(){
    printf("1!+2!+...+9!+10! = %ld\n", sum(10));
    return 0;
}

运行结果: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语言也禁止出现这种情况,会报语法错误,请看下面的代码:

#include <stdio.h>
int a = 10, b = 20, c;
//错误:不能出现加减乘除运算
c = a + b;
//错误:不能出现对其他函数的调用
printf("www.cdsy.xyz");
int main(){
    return 0;
}

 

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门