18.函数递归

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

五.函数递归:
递归的两个必要条件:
1. 存在限制条件,当满足这个限制条件的时候,递归便不再继续
2. 每次递归调用之后越来越接近这个限制条件
写递归代码的时候:
1. 不能死递归,都有跳出条件,每次递归逼近跳出条件
2. 递归层次不能太深
    https://stackoverflow.com/  程序员的知乎

int main()
{
    printf("hehe\n");
    main();  //形成死递归,err

    return 0;
}

练习1:
接收一个整形值(无符号),按照顺序打印它的每一位,例如:输入 1234 ,输出1 2 3 4 
思路: 1234%10          = 4
      1234/10 = 123%10 = 3
      123/10  = 12%10  = 2
      12/10   = 1%10   = 1
      1/10               = 0

递归怎么做?
print(1234)
print(123)      4
print(12)    3  4
print(1)  2  3  4
void print(unsigned int n)
{
    if (n > 9)
    {
        print(n / 10);
    }
    printf("%d ", n % 10);
}
int main()
{
    unsigned int num = 0;
    scanf("%u",&num);        //1234    ,    %u 是无符号整形
                                          //递归 - 函数自己调用自己
    print(num);                    //printf函数可以打印参数部分数字的每一位
    return 0;
}

即使递归满足两个必要条件也可能错误:            
void test(int n)   (出现了栈溢出的情况)   
{                                         
    if (n < 10000) //每次都给test开一个空间     
    {                     //总有一次栈区会溢出的
        test(n + 1);                        
    }                                          
}
int main()                        
{                                                
    test(1);
    return 0;
}

    内存:
    栈区:    局部变量,函数参数,调用函数,时返回值,等临时的变量
            每一个函数的调用,都要再栈区给自己分配一块空间
    堆区:   动态内存分配的  动态内存  malloc / free  calloc  realloc
    静态区:    全局变量  静态变量

练习2
编写函数不允许创建临时变量,求字符串的长度
            my_strlen("bit");
1+            my_strlen("it");
1+1+        my_strlen("t");
1+1+1+        wy_strlen("");
1+1+1+0     =3;

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

    /*int count = 0;      创建的临时变量count了
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;*/
}

int main()
{
    char arr[] = "bit";
                                        //['a'] ['b'] ['c'] ['\0']

                                        //模拟实现一个srelen函数
    printf("%d\n", my_strlen(arr));     //结果为3

    return 0;
}

递归与迭代
练习3 :
求n的阶乘。(不考虑溢出)
int main()
{
    int n = 0;
    scanf("%d", &n);
    int i = 0;
    int ret = 1;
    //迭代
    for (i = 1;i <= n;i++)
    {
        ret *= i;
    }
    printf("%d\n", ret);
    return 0;
}

有一些功能:可以使用迭代的方式实现,也可以使用递归
int Fac(int n)
{
    if (n <= 1)
        return 1;
    else
        return n * Fac(n - 1);
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fac(n);
    printf("%d\n", ret);
    return 0;
}

练习4:
求第n个斐波那契数。(不考虑溢出)
斐波那契数 : 1 1 2 3 5 8 13 21 34 55 ...前两个数的和是第三个
//①递归方法
                                //效率太低 - 重复大量的计算!
int count = 0;
                                //递归可以求解,但是效率太低
int Fib(int n)
{
                                //统计第3个斐波那契数的计算机次数
    if (n == 3)
        count++;
    if (n <= 2)
        return 1;
    else
        return Fib(n - 1) + Fib(n - 2);
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fib(n);

    printf("%d\n", ret);
    prnitf("count = %d\n", count);
    return 0;
}

//②循环方法
int Fib(int n)
{
    int a = 1;
    int b = 1;
    int c = 1;
    while (n > 2)
    {
        c = a + b;
        a = b;
        b = c;
        n--;
    }
    return c;
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fib(n);

    printf("%d\n", ret);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值