第九章 函数(2)

发布于 2021-08-21  552 次阅读


9.2 ANSI C函数原型

在ANSI C标准前,声明函数方案有问题,因为至于要声明函数类型,不用声明任何参数。
ANSI 之前的函数声明,告知编辑器imin()返回int类型的值:
int imin();
然而以上函数声明并未给出imin()的参数个数和类型。因此,如果调用imin()时使用的参数个数不对或类型不匹配,编译器根本不会察觉出来。

9.2.1 问题所在

略 p253

9.2.2 ANSI的解决方案

9.2.3 无参数和未指定参数

假设有下面的函数原型
void print_name()
一个支持ANSI C的编译器会假定用户没有函数原型来声明函数,它将不会检查参数。为了表明确实没有参数,应该在圆括号中使用void关键字:
void print_name(void)
支持ANSI C的编译器解释为print_name()不接受任何参数。然后再调用该函数时,编译器会检查以确保没有使用参数。

9.2.4 函数原型的优点

int imax (int a,int b){return a>b?a:b;}
int main()
{
...
...
...
}

9.3 递归

C允许函数调用它自己,这种调用过程称为递归(recursion)。递归有时候难以捉摸,有时候却很方便使用。结束递归是使用递归的难点,因为如果递归代码中没有终止递归的条件测试部分,一个调用自己的函数会无限递归。
可以使用循环的地方通常都可以使用递归。
有时用循环解决问题比较好,有时递归好。递归方案更简洁,但效率没有循环高。

9.3.1 演示递归

。。显示变量n的值还显示了n的内存地址&n
#include<stdio.h>
void up_and_down(int);
int main()
{
    up_and_down(1);
    return 0;

 } 
 void up_and_down(int n)
 {
    printf("Level %d: n location %p\n",n,&n);
    if(n<4)
        up_and_down(n+1);
    printf("Level %d: n location %p\n",n,&n);
 }

file

9.3.2 递归的基本原理

9.3.3 尾递归

最简单的递归形式是把递归调用置于函数的末尾。即正好在return语句之前。这种形式的递归称为尾递归(tail recursion),因为递归调用在函数尾部。尾递归是最简单的递归形式。因为它相当于循环。
分别用循环和尾递归计算阶乘。一个正整数的阶乘(factorial)是从1到该整数的所有整数的乘积,负数没有阶乘。
#include<stdio.h>
long fact(int n);
long rfact(int n);
int main(void)
{
    int num;

    printf("This program calculates factorials.\n");
    printf("Enter a value in the range 0-12 (q to quit):");
    while(scanf("%d",&num)==1)
    {
        if (num<0)
            printf("No negative numbers,please.\n");
        else if(num > 12)
            printf("keep input under 13.\n");
        else
        {
            printf("loop:%d factorial = %ld\n",num,fact(num));
            printf("recursion:%d factorial = %ld\n",num,rfact(num));
        }
        printf("Enter a value in the range 0-12 (q to quit):");
        }   
        printf("Bye.\n");

        return 0;
 } 
 long fact(int n)       //循环 
 {
    long ans;

    for(ans=1;n>1;n--)
    ans = ans*n;

    return ans;
    }
long rfact(int n)       //递归
{
    long ans;
    if(n > 0)
        ans = n*rfact(n-1);
    else
        ans = 1;
    return ans;
 } 

file

9.3.4 递归和倒序计算

Q:编写一个函数,打印一个整数的二进制数。2进制表示法根据2 的幂来表示数字。
#include<stdio.h>
void to_binary(unsigned long n);

int main(void)
{
    unsigned long number;
    printf("Enter an integer(q to quit):\n");
    while(scanf("%lu",&number)==1)
    {
        printf("Binary equivalent:");
        to_binary(number);
        printf("\n");
        printf("Enter an integer(q to quit):\n");
    }
    printf("Done!.\n");

    return 0;

}
void to_binary(unsigned long n)
{
    int r;

    r = n % 2;
    if(n>=2)
        to_binary(n/2);
    putchar(r ==0 ?'0' : '1');

    return;
}

file

不用递归的话,如果使用这种算法,就必须先把数字存起来

擦肩而过的概率