#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;
}