1.函数递归:
什么是递归:
函数调用自身的编程技巧称为递归。
递归的主要思考方式在于:
把大事化小。
递归的两个必要条件:
·存在限制条件,当满足这个限制条件的时候,递归便不再继续。
·每次递归调用之后越来越接近这个限制条件。
拿一个简单的递归函数举例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
printf("haha\n");
main();
return 0;
}
运行效果如下:
递归不应该是一直打印 haha 吗?为什么会停下呢?
这里我们调试一下,发现弹出如下窗口:
图中关键报错在于:Stack overflow → 栈溢出
2.内存分区:
当我们一直循环往复执行main()函数和printf()打印指令时,
程序会不断地向内存分区中的栈区申请空间,
当空间耗尽时,则会弹出 Stack overflow (栈溢出)的报错,使程序停止。
练习①:接收一个整形值(无符号),按照顺序打印它们每一位
例如输入:1234,输出:1 2 3 4.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void print(int n)
{
if(n>9)
{
print(n/10);
}
printf("%d ",n%10);
}
int main()
{
unsigned int num;
scanf("%d", &num);
print(num);
return 0;
}
如图print()执行顺序如下:
练习②: 编写函数,不允许创建临时变量,求字符串长度。
创建变量版本:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int my_strlen(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "bit";
int len;
//arr是数组,数组传参,传过去的不是整个数组,而是第一个元素的地址
len = my_strlen(arr);//模拟实现一个strlen()函数
printf("len = %d", len);
return 0;
}
不创建变量版本:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = "bit";
int len;
len = my_strlen(arr);
printf("len = %d", len);
return 0;
}
整体思路如下:
使用递归的方法,判断完‘b’后,接着跳到‘i’继续判断,如此往复直到判读到‘\0’
每满足一次if()的判断条件,则+1,如此一直到1+1+1+0,最终可以得出结果为3
上述代码中,1+my_strlen()实际上代替的是count++的作用
而(str+1)代替的是str++的作用。
详细解读如下:
首先框1中(char* str)能看到的是“bit\0”,接着到框1中*str代表的是字母‘b’
判断不为‘\0’后,返回1+...记为字符+1,(str+1)代表的是‘b’的地址往后挪一位,
就到字母‘i’的地址了,接着继续套用函数递归下去,直到判读到‘\0’为止。