函数的递归

文章探讨了递归在计算字符串长度、整数阶乘和斐波那契数的应用,包括基本递归实现及其潜在的栈溢出问题,以及循环方式的替代解决方案。
摘要由CSDN通过智能技术生成

 简单的递归

// **  递归存在限制条件 **
// **  每次递归调用之后越来越接近这个限制条件  **


int main()
{
    printf("hehe\n");
    main();
    return 0;
}

 

 实例1:将1234,拆分成1 2 3 4打印

void print(int n)  //n=1234
{
    if (n > 9)  // 这一条可以让递归停止
    {
        print(n / 10);
    }
    printf("%d ", n % 10);
}
int main()
{
    unsigned int num = 0;
    scanf("%d", &num);  //1234
    //递归
    print(num);
    //可以进行以下拆分
    //print(1234)
    //print(123) 4
    //print(12) 3 4
    //print(1)2 3 4

    return 0;
}

 

  

 一开始是递:图一经过if语句判断,将n/10=12,传递给图二,然后再经过if语句判断,n/10=1,传递给图三,然后图三n=1,不执行if函数,直接打印1,然后经行归的过程

 归的过程:图三是由图二的printf(n/10)来的,就归到图二的printf(n/10),然后往下执行printf("%d ",n%10),此时的n=12,打印结果为2,然后由图二归到图一printf(n/10),往下走printf("%d ",n%10),此时的n=123,打印结果为3

最终打印结果为1 2 3 

实例2: 求字符串长度

不使用库函数求字符串长度
//int my_strlen(char* str)  //这里接收的不是整个arr数组,而是arr数组的首个元素的地址
//{
//    int count = 0;  //临时变量
//    while (*str != '\0')
//    {
//        count++;
//        str++;
//    }
//    return count;
//}


不使用库函数和临时变量求字符串长度

1.不使用库函数求字符串长度
int my_strlen(char* str)  //这里接收的不是整个arr数组,而是arr数组的首个元素的地址
{
    int count = 0;  //临时变量
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}
2.不使用库函数和临时变量求字符串长度
递归的方法
my_strlen("bit");
1+my_strlen("it");
1+1+my_strlen("t");
1+1+1+my_strlen("");
1+1+1+0=3

int my_strlen(char* str)
{
    if (*str != '\0')
    {
        return 1 + my_strlen(str + 1);
    }
    else
        return 0;
}

主函数:

int main()
{
    char arr[] = "bit";
    //printf("%d\n", strlen(arr));  //求字符串长度

    //模拟实现一个strlen函数
    int len = my_strlen(arr);  //arr是数组,数组传参,传过去的不是整个数组,而是数组的首个元素的地址
    printf("%d\n", len);


    return 0;
}

 

 

 

 

 

 

 

 int my_strlen(char* str)中的str是arr中首个元素的地址,用if语句判断,如果不遇到'\0',图一就要返回 1 + my_strlen(str + 1),然后传递给图二 int my_strlen(char* str)的str,往下执行,再将1 + my_strlen(str + 1)传递给图三,然后图三再传到图四,这个时候就遇到'\0',要返回0,将0返回到图三的my_strlen(str + 1),就是1+my_strlen(str + 1)=1+0=1,然后在返回给图二的my_strlen(str + 1),就是1+my_strlen(str + 1)=1+1=2,再返回给图一的my_strlen(str + 1),就是1+my_strlen(str + 1)=1+2=3,最后返回主函数的 my_strlen(arr),结果就为3

实例3 :求n的阶乘

1.循环的方式
int Facl(int n)
{
    int i = 0;
    int ret = 1;
    for (i = 1; i <= n; i++)
    {
        ret *= i;
    }
    return ret;
}
int main()
{
    int ret = 0;
    int n = 0;
    scanf("%d", &n);
    ret = Facl(n);  //循环的方式
    printf("n!= %d\n", ret);
    return 0;
}

2.递归的方式
int Facl2(int n)
{
    if (n <= 1)  
        return 1;
    else
        return n * Facl2(n - 1); //返回n*n-1
}
int main()
{
    int ret = 0;
    int n = 0;
    scanf("%d", &n);
    ret = Facl2(n);  //递归的方式
    printf("n!= %d\n", ret);
    return 0;
}

 

 

实例4:求第n个斐波那契数(【【【{重要}】】】)

斐波那契数列:前两个数的和等于第三个数
1 1 2 3 5 8 13 21 34 55 89 .....

1.递归的方式(有的时候会栈溢出)
int count = 0;
int Fib(int n)
{
    //if (n == 3)//测试第三个斐波那契数的计算次数
    //{
        //count++;
    //}
    if (n <= 2)
        return 1;
    else
        return Fib(n - 1) + Fib(n - 2);
}

2.递归并不适合解决此问题
//采用常规的循环方式
int Fib(int n)
{
    int a = 1;
    int b = 1;
    int c = 1; //这里不能写0,当n=1,n=2的时候,不执行while循环,直接返回c,如果这时的c=0,就错了
    while (n > 2)
    {
        c = a + b;
        a = b;
        b = c;
        n--;   //这一条时为了减少不必要的循环,例如n=4,每执行一次循环,n就减去1,执行两次之后自动跳出循环
    }
    return c;
}
int main()
{
    int n = 0;
    int ret = 0;
    scanf("%d", &n);
    //TDD - 测试驱动开发
    ret = Fib(n);
    printf("%d\n", ret);
    //printf("count= %d\n",count);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值