C语言设计

第27章


对此,各系统的规定不一定相同。
介绍 printf 函数时已提到过,这里从函数调用的角度再强调一下。
【例 8.3】
main()
{
    int i=8;
    printf("%d %d %d %d ",++i,--i,i++,i--);
}
如按照从右至左的顺序求值。运行结果应为:
    8
    7
    7
    8
如对 printf 语句中的++i,--i,i++,i--从左至右求值,结果应为:
    9
    8
    8
    9
谭浩强      C 语言程序设计               2001 年 5 月 1 日
应特别注意的是,无论是从左至右求值, 还是自右至左求值,其输出顺序都是不变的,
即输出顺序总是和实参表中实参的顺序相同。由于 Turbo C 现定是自右至左求值,所以结果
为 8,7,7,8。上述问题如还不理解,上机一试就明白了。
8.4.3 被调用函数的声明和函数原型
在主调函数中调用某函数之前应对该被调函数进行说明(声明),这与使用变量之前要
先进行变量说明是一样的。在主调函数中对被调函数作说明的目的是使编译系统知道被调函
数返回值的类型,以便在主调函数中按此种类型对返回值作相应的处理。
其一般形式为:
        类型说明符 被调函数名(类型 形参,类型 形参…);
或为:
        类型说明符 被调函数名(类型,类型…);
括号内给出了形参的类型和形参名,或只给出形参类型。这便于编译系统进行检错,以
防止可能出现的错误。
例 8.1 main 函数中对 max 函数的说明为:
int max(int a,int b);
或写为:
        int max(int,int);
C语言中又规定在以下几种情况时可以省去主调函数中对被调函数的函数说明。
1) 如果被调函数的返回值是整型或字符型时,可以不对被调函数作说明,而直接调用。
这时系统将自动对被调函数返回值按整型处理。例 8.2 的主函数中未对函数 s 作说
明而直接调用即属此种情形。
2) 当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数
再作说明而直接调用。例如例 8.1 中,函数 max 的定义放在 main 函数之前,因此
可在 main 函数中省去对 max 函数的函数说明 int max(int a,int b)。
3) 如在所有函数定义之前,在函数外预先说明了各个函数的类型,则在以后的各主调
函数中,可不再对被调函数作说明。例如:
    char str(int a);
    float f(float b);
    main()
    {
……
    }
    char str(int a)
    {
……
    }
    float f(float b)
    {
……
    }
其中第一,二行对 str 函数和 f 函数预先作了说明。因此在以后各函数中无须对
谭浩强      C 语言程序设计               2001 年 5 月 1 日
str 和 f 函数再作说明就可直接调用。
4) 对库函数的调用不需要再作说明,但必须把该函数的头文件用 include 命令包含在
源文件前部。
8.5 函数的嵌套调用
C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下
一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出
现了函数的嵌套调用。即在被调函数中又调用其它函数。这与其它语言的子程序嵌套的情形
是类似的。其关系可表示如图。
图表示了两层嵌套的情形。其执行过程是:执行 main 函数中调用 a 函数的语句时,即
转去执行 a 函数,在 a 函数中调用 b 函数时,又转去执行 b 函数,b 函数执行完毕返回 a
函数的断点继续执行,a 函数执行完毕返回 main 函数的断点继续执行。
2
【例 8.4】计算s=2 !+32!
本题可编写两个函数,一个是用来计算平方值的函数 f1,另一个是用来计算阶乘值的
函数 f2。主函数先调 f1 计算出平方值,再在 f1 中以平方值为实参,调用 f2 计算其阶乘值,
然后返回 f1,再返回主函数,在循环程序中计算累加和。
long f1(int p)
{
    int k;
    long r;
    long f2(int);
    k=p*p;
    r=f2(k);
    return r;
}
long f2(int q)
{
    long c=1;
    int i;
    for(i=1;i1)
按公式可编程如下:
long ff(int n)
{
    long f;
谭浩强      C 语言程序设计               2001 年 5 月 1 日
    if(n<0) printf("n<0,input error");
    else if(n==0||n==1) f=1;
    else f=ff(n-1)*n;
    return(f);
}
main()
{
    int n;
    long y;
    printf(" input a inteager number: ");
    scanf("%d",&n);
    y=ff(n);
    printf("%d!=%ld",n,y);
}
程序中给出的函数 ff 是一个递归函数。主函数调用 ff  后即进入函数 ff 执行,如果
n<0,n==0 或 n=1 时都将结束函数的执行,否则就递归调用 ff 函数自身。由于每次递归调用
的实参为 n-1,即把 n-1 的值赋予形参 n,最后当 n-1 的值为 1 时再作递归调用,形参 n 的值
也为 1,将使递归终止。然后可逐层退回。
下面我们再举例说明该过程。设执行本程序时输入为 5,即求 5!。在主函数中的调用
语句即为 y=ff(5),进入 ff 函数后,由于 n=5,不等于 0 或 1,故应执行 f=ff(n-1)*n,即 f=ff(5-1)*5。
小说推荐
返回首页返回目录