C语言中的递归函数
我试图理解递归。具体来说,有两个函数我无法获得 第一个是我在网上遇到的一个例子:C语言中的递归函数,c,recursion,C,Recursion,我试图理解递归。具体来说,有两个函数我无法获得 第一个是我在网上遇到的一个例子: #include <stdio.h> void printnum(int begin) { printf("%d", begin); if (begin < 9) { printnum(begin + 1); } printf("%d", begin); } void main() { printnum(1); } #包括 v
#include <stdio.h>
void printnum(int begin) {
printf("%d", begin);
if (begin < 9) {
printnum(begin + 1);
}
printf("%d", begin);
}
void main() {
printnum(1);
}
#包括
void printnum(int begin){
printf(“%d”,开始);
如果(开始<9){
printnum(开始+1);
}
printf(“%d”,开始);
}
void main(){
printnum(1);
}
此函数的输出为:123456789987654321
我能理解它是如何从1到9的,但我不明白的是,如果没有任何值减少,它是如何倒退的。那怎么办?O.O
我无法获得的第二个函数是我想到的:
#include <stdio.h>
int dbl(int i) {
if (i == 1) {
return 1;
}
return dbl(i - 1) + dbl(i - 1);
}
void main() {
int i;
for (i = 1; i < 10; i++) {
printf("%d\t", dbl(i));
}
}
#包括
intdbl(inti){
如果(i==1){
返回1;
}
返回dbl(i-1)+dbl(i-1);
}
void main(){
int i;
对于(i=1;i<10;i++){
printf(“%d\t”,dbl(i));
}
}
所以,这个打印出来的是:1 2 4 8 16 32 64 128 256
这太令人困惑了,在同一个函数中有两个函数调用,我无法理解这背后的逻辑。函数打印每个数字的双精度的确切过程是什么?对于第一个:
“向后数字的打印”来自递归函数中的第二条打印语句。当第九次递归调用中
begin
为9时,if语句失败,递归结束。然后它继续打印9并退出特定的递归调用,然后返回到上一个递归调用,其中begin
是8。请记住,一直到现在,我们都在if语句的末尾。然后我们退出第8个递归调用,返回begin
为7的位置,依此类推 它实际上并没有减少,因为函数在完成之前一直保留在堆栈上
您有两个调用来打印begin
的值:
void printnum(int begin) {
printf("%d", begin); //here
if (begin < 9) {
printnum(begin + 1);
}
printf("%d", begin); //and here
}
以下是调用函数时发生的事情的要点: 正在运行的代码暂停,函数开始运行。当函数结束时,暂停的代码将在原来的位置重新启动
main:
code
code
function -----> function:
<----- print
code ---- return
main:
代码
代码
功能------>功能:
功能:
功能:
-对于第一个示例:
首先,您的begin
变量是1
,直接打印(printf(“%d”,begin);
)
if语句称为递归锚点。8次begin
变量的值小于9
,因此函数printnum
生成如下调用堆栈:
printnum(2);
printnum(3);
printnum(4);
printnum(5);
printnum(6);
printnum(7);
printnum(8);
printnum(9);
现在记住递归锚点:begin
变量现在是9
,因此跳过递归,第二个print命令printf(“%d”,begin))代码>从9
向后执行到1
编辑:第二个示例
这里的if
语句也是递归锚点,它在for
循环的第一次调用中产生true
如果使用2
调用dbl
,它将返回添加的dbl(1)+dbl(1)
,结果是2
如果使用3
调用它,它将返回添加的dbl(2)+dbl(2)
,这将导致
(dbl(1) + dbl(1))
+
(dbl(1) + dbl(1))
,最终结果是4
希望它能帮助=)对于第一个递归函数,只要想象一下这个函数没有递归调用
printnum(1);
将输出
11
但是当您递归调用该函数时,第二个print方法在所有递归调用完成之前不会被调用。在本例中,您有9个递归调用。因此,在函数到达递归函数的第二部分之前,它必须执行自己9次(直到递归调用,这意味着只有第一个print语句)。因此,对于输出123456789,只调用以下行:
printf("%d", begin);
if (begin < 9) {
printnum(begin + 1);
}
为您提供输出987654321的后半部分。递归函数是一个反复调用自身的函数
想象一下,你有一个圆形容器,你必须把盘子放在那里。你把第一个盘子放进去,然后是第二个,然后是第三个,依此类推。要到达第一个盘子,您需要移除它上方的所有盘子
同样,当您调用递归函数时,它会执行某些操作,然后再次调用自身。现在,函数的第二个实例正在执行,第一个实例处于暂停状态。
第二个实例现在调用第三个实例。第三个实例将完全执行,然后退出,现在控制移回第二个实例。中的第二个实例现在已完成,控件将返回到第一个实例。
现在第一个实例将被终止
递归就是这样发生的
例如,假设您必须计算一个数字的阶乘:
int fact(int n){
if(n==1)
return 1;
else
return n*fact(n-1);
}
void main(){
printf(fact(3));
}
这将打印6。
它的工作原理如下:
printnum(2);
printnum(3);
printnum(4);
printnum(5);
printnum(6);
printnum(7);
printnum(8);
printnum(9);
事实(3)将返回3*事实(2)。
事实(2)将返回2*事实(1)。
事实(1)将返回1
因此,该语句实际上看起来像-->3*(事实(2))-->3*(2*事实(1))。
这将归结为3*2*1
希望这能有所帮助。函数的printnum(begin)
功能执行以下操作:
- 首先,它打印编号
begin
- 然后它调用
printnum(begin+1)
来打印所有较大的数字
- 然后打印另一个
begin
所以它做的第一件也是最后一件事就是打印它的数字,在这两者之间,所有更高的数字都会被打印出来
对于第二个函数,您可以这样考虑:
printnum(2);
printnum(3);
printnum(4);
printnum(5);
printnum(6);
printnum(7);
printnum(8);
printnum(9);
- 什么是数据库(1)
?是1。不涉及递归
什么是数据库(2)
?它是db(1)+db(1)
。这是1+1=2,因为我们已经知道db(1)
是1
db(2)+db(2)
。因为我们知道,db(2)
等于2,所以这是4d呢
int fact(int n){
if(n==1)
return 1;
else
return n*fact(n-1);
}
void main(){
printf(fact(3));
}
void printnum(int begin) {
printf("%d", begin);
if (begin < 9) {
printnum(begin + 1);
} //place break point here, and single step through rest of code.
//You will see execution flow will bounce back and forth from here....
printf("%d", begin); //....to here as the function "unwinds" from recursion.
}