如何结束递归函数?

问题描述 投票:2回答:6

我正在尝试做一个简单的递归函数示例(直接和间接),我似乎无法完成它你能帮我解释一下原因吗? (此外,我正在尝试在此程序中同时执行Direct和Indirect)感谢您的帮助。

int Print();
int main()
{
    Print();
    return 1;
}
int Print()
{
    int i=0;
    do
    {
        printf("%d",i);
        i++;
    }while(i<10);
    if(i==9)
        return 1;
    Print();
}

编辑:直接和间接的递归,直接应该从同一个函数内部调用而间接是从函数外部调用的,我也为不格式化和跳过而道歉

c recursion
6个回答
3
投票

i成为函数的参数。

#include <stdio.h>

int Print(int);
int main()
{
    Print(9);
    return 1;
}
int Print(int i)
{
    if (i <= 0) {
      return 1;
    }
    printf("%d",i);
    return Print(i-1);
}

do...while部分看起来很奇怪,你确定你需要吗?


1
投票

在你的情况下,我永远不会是9岁。因此一次又一次地调用Print()。


1
投票

对于根据C标准的初学者,没有参数的函数main应声明为

int main( void )

至于递归函数(当它被定义为int Print( void )时应该声明),那么有几个问题。

第一个是函数返回什么,虽然它有返回类型int

int Print()
{
    // ...
    Print();
}

其次是由于do-while循环

do
{
    printf("%d",i);
    i++;
}while(i<10);

本声明中的条件

if(i==9)
    return 1;

永远不会是真的,因为在循环之后变量i等于10。所以函数有一个无限递归。

而不是循环,你应该使用函数本身的调用。

可以按照以下说明程序中所示的方式定义功能。

#include <stdio.h>

void direct_print( void )
{
    enum { N = 10 };
    static int i = N;

    if ( --i ) 
    {
        direct_print();
    }
    printf( "%d ", i );
    ++i;
}

void reverse_print( void )
{
    enum { N = 10 };
    static int i = N;

    printf( "%d ", --i );

    if ( i ) 
    {
        reverse_print();
    }
    ++i;
}


int main(void) 
{
    direct_print();
    putchar( '\n' );
    reverse_print();
    putchar( '\n' );

    return 0;
}

它的输出是

0 1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1 0 

或者更直接的方法来定义函数direct_printreverse_print如下

#include <stdio.h>

void direct_print( void )
{
    const unsigned int N = 10;
    static unsigned int i;

    if ( i < N )
    {
        printf( "%u ", i++ );
        direct_print();
    }
    else
    {
        i = 0;
    }
}

void reverse_print( void )
{
    const unsigned int N = 10;
    static unsigned int i;

    if ( i < N )
    {
        printf( "%u ", N - ++i );
        reverse_print();
    }
    else
    {
        i = 0;
    }
}

int main(void) 
{
    direct_print();
    putchar( '\n' );
    reverse_print();
    putchar( '\n' );

    return 0;
}

考虑到函数将更灵活,如果不是在函数体内使用参数的幻数10

例如

#include <stdio.h>

void direct_print( unsigned int n )
{
    static unsigned int i;

    if ( i == 0 ) i = n;

    if ( n )
    {
        printf( "%u ", i - n );
        direct_print( n - 1 );
    }

    if ( i == n ) i = 0;
}

void reverse_print( unsigned int n )
{
    if ( n-- )
    {
        printf( "%u ", n );
        reverse_print( n );
    }
}


int main(void) 
{
    direct_print( 10 );
    putchar( '\n' );
    reverse_print( 10 );
    putchar( '\n' );

    return 0;
}

输出与前一个程序的显示相同

0 1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1 0 

0
投票

来自莫斯科的弗拉德已经对OP问题进行了很好的写作。

我想用stop_condition添加一个解决方案。

#include<stdio.h>

void Print(int i, int stop_condition);

int main(void)
{
  Print(0, 10);
  putchar( '\n' );

  return 0;
}

void Print(int i, int stop_condition)
{
    printf("%d ",i++);

    if(i<stop_condition)
        return Print(i, stop_condition);
}

输出:

0 1 2 3 4 5 6 7 8 9 

0
投票

在你的函数返回条件if(i==9)永远不会满足,因为它始终是i=10。所以你的Print()函数一直在递归地调用。首先,您需要准确了解使用递归函数所需的条件/情况?在您的示例中,您将在while loop的帮助下打印1到9的值。现在,如何通过使用递归函数来实现相同的功能?

 void Print(int i)
 {
       if( i == 0 )//when i become 0 you are not printing but returning 
          return;
       else
          Print(--i);//decrement the value by one each time you are calling it recursively
       printf("%d\n",i);
}

而你称之为: -

Print(10); // now it will print from 1 till 10;

但它是如何工作的?当您第一次使用参数10调用此函数时,在条件if(i == 0)中它将失败,因为第一次调用中i的值为10.在该条件下,O / S将存储所有中间数据/输出(在这种情况下,它将存储i = 10;)和函数的IP(指令指针,最后执行状态是Print(--i);,它是每个递归函数中最后执行的语句)。它将在第一次递归调用(Print( - i))中调用Print(9);。整个过程将持续到Print(0)。但当它调用Print(0)函数将返回而不打印值,因为它将在条件if( i == 0 )后返回,因为这里i成为0。从这一点开始,它将返回上一个呼叫。它如何回到之前的通话?一旦递归函数返回它,pops堆栈并首先获得IP,它是中间输出,即i的值。在这种情况下,当它第一次返回时,i的当前值是1,因此在printf中它将打印1.因为这是函数的最后一行,并且根据IP是要执行的剩余指令。所以它会正常返回。现在它将从堆栈中获取IP,其中函数的变量i的中间值为2,因此它将打印2并返回并且这将继续直到它在第一次调用中达到它的值为10并且在它打印10之后它将返回到main。

希望这会帮助你。


-1
投票

这是一个使用递归的有限循环,因子为5

              i = 5;
              fact=1;
               while(i)
              {
                 fact = fact*i;
                  i- -;
              }
© www.soinside.com 2019 - 2024. All rights reserved.