递归的定义:
一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。
下面是一个最简单的递归:
#include<stdio.h>
int main()
{
printf("sugar\n");
main();
return 0;
}
会发现程序出现像死循环一样的结果,因为打印了sugar后,又调用了main()函数,函数又从头开始,继续打印sugar。这种函数调用自己本身的现象就是函数的递归(虽然看该程序有一定的问题)
错误提示:stack overflow 栈溢出
策略:将大型的复杂问题层层转化为一个与原问题相似的规模较小的问题来求解。
例1.接受一个整型值,按顺序打印其每一位。
例如:输入1234,输出1 2 3 4.
思路:
1234%10=4 1234/10=123
123%10=3 123/10=12
12%10=2 12/10=2
2%10=1 1/10=0
所以我们可以自下而上的书写代码:
#include<stdio.h>
void print(unsigned int n) //打印在屏幕上就行,不需要返回值
{
if (n > 9)
{
print(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
scanf_s("%u", &num);
print(num); //可以打印参数部分数字的每一位
return 0;
}
我们来看一下这个程序的流程:
1.首先输入123后num=123,调用print()函数
2.进入print()函数内部,此时n=123
3.n=123>9,判断为真,再次调用print()函数,此时程序停在if中,记作a位置
4.此时n=123/10=12>9 ,判断为真,再次调用print()函数,此时程序停在if中,记作b位置
此时n=12/10=1
5.打印12%10=2,并结束该函数的调用,返回到a位置
6.打印123%10=3,并结束该函数的调用,返回到主函数中,return 0;结束
7.此时屏幕中打印出1 2 3
递归的限制条件:
- 存在限制条件,当不满足限制条件,递归便不再继续
- 每次递归调用之后,越来越接近这个限制条件
但有可能会出现栈溢出的错误(stack overflow)
内存中有栈区(存放局部变量,函数形参),堆区(动态内存分配),静态区(存放全局变量,静态变量)
每一次函数调用,都要在内存中生成一块区间(xxx的栈帧空间,空间中放局部变量等等)
当栈区内存不够时,就会出现栈溢出现象(递归次数太多造成)
所以在限制条件中增加一条:
3.递归的层次不能太深,会出现栈溢出
https://.stackoverflow.com/ 程序员的知乎
例2.编写函数不允许创建临时变量,求字符串长度
如果使用临时变量:
#include<stdio.h>
#include<string.h>
int my_strlen(char* str)
{
int count = 0;
while(*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "sugar";
printf("%d\n", my_strlen(arr));
return 0;
}
可以完成操作,但创建了临时变量count
思路:
my_strlen("sugar");
1+my_strlen("ugar");
1+1+my_strlen("gar");
1+1+1+my_strlen("ar");
1+1+1+1+my_strlen("r");
1+1+1+1+1+my_strlen("\0");
#include<stdio.h>
#include<string.h>
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = "sugar";
printf("%d\n", my_strlen(arr));
return 0;
}
数组的指针传递的是第一个元素的指针,即's'的指针,my_strlen看到的是“sugar”
str+1则是指针+1,my_strlen看到的是“ugar”
以此类推……