系列文章目录
深度剖析:数据
深度剖析:递归
深度剖析:结构体
深度剖析:动态内存管理
深度剖析:文件操作
深度剖析:预处理
前言
递归类似于循环,但比循环更加灵活。
递归思想: 将大事化小,将复杂的问题用简单的代码去实现。
一、递归是什么?
1.递归是一种算法思想
2.递归是函数调用自身的过程
3.像循环一样不断的重复某一件事
二、递归与循环
1.循环
do while: 每次循环必定会先执行一次,再进行判断
void do_while(int n) {
do {
printf("不好好学习,没有工作\n");
} while (--n);
printf("好好学习,找到好工作\n");
}
程序运行时一定会先执行不好好学习,没有工作
然后循环判断是否好好学习
,如果满足条件
则循环停止。
输出结果:
不好好学习,没有工作
不好好学习,没有工作
不好好学习,没有工作
好好学习,找到好工作
2.递归
递归:每次循环必定会先执行一次,再进行判断
要点:
1.要设置停止递归的条件(防止死递归)
2.每次调用通常要改变传入的值
3.先由外向内,再由内向外,进去几次,出来几次
4.递归过于深入可能出现栈溢出
void recursion(int n) {
printf("不好好学习,没有工作\n");
if (n) {
recursion(n - 1);
}
printf("好好学习,找到好工作\n");
}
程序运行时必定先执行不好好学习,没有工作
如果符合条件再次进入函数,再次执行。当不符合条件时执行下一步好好学习,找到好工作
在这里,是由内向外打印。
输出结果
不好好学习,没有工作 //第一次调用
不好好学习,没有工作 //第二次调用
不好好学习,没有工作 //第三次调用
不好好学习,没有工作 //第四次调用
.
.
.
好好学习,找到好工作 //第四次调用
好好学习,找到好工作 //第三次调用
好好学习,找到好工作 //第二次调用
好好学习,找到好工作 //第一次调用
同样是必定执行一次, 而递归是通过不断调用自己来实现循环。
三.练习
练习1.接受一个整型值(无符号),按照顺序打印它的每一位。
例如:
输入:1234
输出:1 2 3 4
#include <stdio.h> void print(int n) {
if(n>9) {
print(n / 10);
}
printf("%d ", n % 10);
}
练习2.编写函数不允许创建临时变量,求字符串的长度。
int Strlen(const char *str) {
if (*str == '\0') {
return 0;
}
else {
return 1 + Strlen(str + 1);
}
}
注解:Strlen(str + 1) 为每次调用时改变条件。返回时 + 1表示此次调用找到1 + 返回值个字符串,依此返回,每次返回都 + 1
练习3.n的阶乘
int factorial(int n) {
if(n <= 1) {
return 1;
}
else {
return n * factorial(n-1);
}
}
练习4.递归实现逆序字符串数组的内容
void reverse_string(char *str) {
int len = strlen(str);
char tmp = *str;
*str = *(str + len - 1);
*(str + len - 1) = '\0';
if (len > 3) {
reverse_string(str + 1);
}
*(str + len - 1) = tmp;
}
注解:tmp先记录首字符内容,*(str + len - 1) = '\0';将最后一个字符变为‘\0’ 方便下一次找到倒数第二个字符
注解:最后再将tmp赋值给原先赋值'\0'的位置,完成交换