Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的递归函数_C_Recursion - Fatal编程技术网

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
  • 什么是数据库(3)?它是
    db(2)+db(2)
    。因为我们知道,
    db(2)
    等于2,所以这是4
  • d呢
    
    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.
    }