一.引入部分
我们先来看一个题目:
接受一个整型值(无符号),按照顺序打印它的每一位数字,如输入1234,则程序应输出1 2 3 4
示例代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void print(int n){
if (n > 9){
print(n/10);
}
printf("%d ",n%10);
}
int main(void){
unsigned int num = 0;
printf("请输入:");
scanf("%d", &num);
print(num);
return 0;
}
我们来分析一下这段代码:首先我们看main()函数中的内容,由于题目要求接受值的数据类型为无符号整型,所以我们使用unsigned来对变量修饰,随后初始化变量num(num=0),调用printf()函数提示用户进行输出,再利用scanf()函数获取用户输入的内容并赋值给变量num,随后将num的值传入自定义函数,print()中,我们再来看print()函数中的内容,函数中调用了if语句,当n>9也就是说数字的值是十位数以上的时候则再调用print()函数,将n/10以后的结果传入函数中,这就是递归,接下来我们想一想123传入print()函数,还是满足if语句的入口条件,再次将n/10的结果传入print()函数中,我们接下来用图片的形式来观察程序的执行步骤:
这里我们只看if语句中的内容,先不考虑printf()函数,可以看到当函数递归的时候,原先的1234被除以10后变成123,再将123除以10变成12,最后将12除以10得到1,1<9不满足if语句的入口条件,所以不执行if语句中的内容,我们再来看一下加上printf()语句的结果:
当不满足if语句入口条件后便会执行printf()语句,printf()语句会输出n%10的结果,这里的n为1,1%10的结果为1,执行完成后会返回到上一个函数,这时候则会执行上一个函数中的printf()语句,n%10,此时n=12,12%10则等于2,所以会输出2,执行完成语句后便再返回到上一个函数中,以此类推,最终就会输出 1 2 3 4,程序运行截图:
我们之前写过一段代码:
#include<stdio.h>
int main(void)
{
main();
return 0;
}
这段代码会导致栈溢出,原因就是递归调用并没有限制,是无条件的递归,所以导致了栈溢出,那么我们上面的程序如果改成一下形式呢?
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
void print(int n){
if (n > 9){
print(n);
}
printf("%d ",n%10);
}
int main(void){
unsigned int num = 0;
printf("请输入:");
scanf("%d", &num);
print(num);
system("pause");
return 0;
}
我们将if语句中传入print()函数的值不除以10,那会发生什么呢?
这就会导致我们传入的数字一直是1234,一直死循环,最终导致栈溢出,所以递归一定要有条件的限制
2023/8/16
王起舟