【问题标题】:Problem using recursion trying to make a descending list in c使用递归尝试在 c 中创建降序列表时出现问题
【发布时间】:2020-12-11 09:51:41
【问题描述】:

我遇到了递归问题,我试图让用户输入一个数字并将数字打印到屏幕上的数字 1。

(如果您向我解释解决方案的工作原理,我将不胜感激,因为我正在学习,这对我来说非常复杂。)

例如,用户输入数字 5,我希望它显示: 5. 4. 3. 2. 1.

#include<stdio.h>
int list(int n);

int main(){
    int i,number;
    
    printf("Enter a number: ");
    scanf("%d",&number);
    
    for(i = number;i > 0;i--){
        printf("%i.\n", list(i));
    }
    
    return 0;   
}


int list(int n){
    if(n == 1||n == 0){
        return 1;
    }
    else{
        return list(n); 
    }
}

【问题讨论】:

  • 仅供参考,return list(n) 当您传递的参数值与您在第一名?仅供参考,这个练习的重点是递归。 IE。 for 循环不应该在这段代码中,输出应该在递归函数本身中。
  • 这些都没有任何意义。您希望list(n) 返回n,对吗?使用递归来获得你已经拥有的值有什么意义?在任何情况下,如果你从list(n) 中调用list(n),你只会递归直到耗尽你的堆栈空间。

标签: c recursion printf function-definition


【解决方案1】:

这个函数

int list(int n){
    if(n == 1||n == 0){
        return 1;
    }
    else{
        return list(n); 
    }
}

没有意义,当n不等于0和1时,自身无限递归调用会产生栈溢出。

即使你会用以下方式改变它

int list(int n){
    if(n == 1||n == 0){
        return 1;
    }
    else{
        return list(n - 1);    // <=== 
    }
}

但是,如果参数n 具有负值,该函数会再次产生堆栈溢出。此外,对于非负值,该函数将始终返回 1 并且不输出任何内容。

所以函数本身没有任何意义。

注意函数的参数类型应该是unsigned int,因为函数不是为处理负数而设计的。而函数int的返回类型也没有多大意义。

下面是一个演示程序,展示了如何声明和定义函数。

#include <stdio.h>

void list( unsigned int n )
{
    n == 0 ? ( ( void )putchar( '\n' ) ) : ( printf( "%d.", n ), list( n - 1 ) );
}

int main(void) 
{
    while ( 1 )
    {
        printf( "Enter a non-negative number (0 - exit): " );
        
        unsigned int n;
        
        if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
        
        putchar( '\n' );
        list( n );
        putchar( '\n' );
    }
    
    return 0;
}

程序输出可能看起来像

Enter a non-negative number (0 - exit): 5

5.4.3.2.1.

Enter a non-negative number (0 - exit): 4

4.3.2.1.

Enter a non-negative number (0 - exit): 3

3.2.1.

Enter a non-negative number (0 - exit): 2

2.1.

Enter a non-negative number (0 - exit): 1

1.

Enter a non-negative number (0 - exit): 0

享受吧!:)

【讨论】:

    【解决方案2】:

    如果您想使用递归,则不需要 for 循环。

    #include<stdio.h>
    
    void list(int n);
    
    int main() {
      int i, number;
    
      printf("Enter a number: ");
      scanf("%d", & number);
      /*   for(i = number;i > 0;i--){
             printf("%i.\n", list(i));
         }*/
      list(number);
      return 0;
    }
    //Prints the number and calls its 
    //preceding number untill 1 is encountered
    void list(int n) {
      if (n == 1 || n == 0) {
        printf("1.");
      } else {
        printf("%d. ", n);
        //return list(n) never returns previous number 
        return list(n - 1); //returns (n-1)'s previous numbers
      }
    }
    

    如果你只是想使用 for 循环,你可以使用以下代码。

    for(int i = number ; i>0 ; i--)
      printf("%d. ",i);
    

    【讨论】:

      【解决方案3】:

      正如前面的答案所指出的,您不需要为此进行递归,但如果您愿意,可以这样做。此版本将所有结果合并为一个字符串。

      #include <stdio.h>
      #include <stdlib.h>
      
      const char* list(int n);
      
      int main(){
          int i,number=5;
          
          printf("Enter a number: ");
          scanf("%d",&number);
          
          printf("%s", list(number));  // full list 5 4 3 2 1
      
          return 0;   
      }
      
      
      const char* list(int n){
          if(n == 1||n == 0){
              return "1";
          }
          else {
              char *str = (char*)malloc(20);
              sprintf(str, "%d %s", n, list(n-1)); // this value plus remaining values
              return str; 
          }
      }
      

      输出

      5 4 3 2 1
      

      【讨论】:

        猜你喜欢
        • 2021-02-10
        • 2019-04-19
        • 1970-01-01
        • 2022-10-15
        • 2015-01-20
        • 2020-09-02
        • 1970-01-01
        • 2018-02-13
        • 1970-01-01
        相关资源
        最近更新 更多