用C语言递归计数到一定数量

时间:2018-10-30 18:51:55

标签: c

我一直在尝试编写一个程序,直到递归地输入用户输入的数字(f,ex:10)为止。

如果用户输入10,程序将必须打印出:1,2,3,4,5,6,7,8,9,10。

我得到一个[1] 49348 segmentation fault ./recs.exe,我想知道为什么我将来会得到它来防止它发生。

这是我的代码:

#include <stdio.h>

int numbers(int n);

int main(int argc, char const *argv[]) {

  int number;

  int i;

  printf("Put a number and the program will do everything for ya.\n");

  printf("Number: ");

  scanf("%d", &number);

  for(i=0;i<=number;i++){

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

  }

}

int numbers(int n){

  if(n==0||n==1){

    return n;

  } else {

    return(numbers(n+1)); // I think the problem is here.

  }

}

希望你们能解释我的错误并帮助我理解为什么会发生这种情况,以帮助我避免这种愚蠢的错误。谢谢:)

4 个答案:

答案 0 :(得分:2)

您的算法存在一些问题。

  1. for循环多次调用numbers程序,并多次启动递归。您只需要启动一次,对吧?

  2. 您用n+1调用递归,实际上每次下一次调用都使用增量值,该值可以无限地递增。您的递归没有退出,并且会因内存不足或崩溃而死亡。

要解决第一个问题,只需实例化一次。

要正确打印它,您需要在递归中包含打印语句。

对于第二个问题,您可以采取不同的方法。以下内容最容易理解,并且将max作为第二个参数传递。

 void numbers(int n, int max) {
     printf(%d ", n);
     if (n >= max)
        return;
     numbers (n + 1, max);
  }

  int main() {
    ...
    numbers(1, number);
  }

一种更有效的方法是使用单个参数并将其倒数至0。但是在打印时必须小心。对于您的情况,如果需要值的递增顺序,则必须确保在从递归返回后 后进行打印。

这是实现第二种方法的程序:

#include <stdio.h>

void numbers(int n);
int main(int argc, char const *argv[]) {
  int number;
  int i;
  printf("Put a number and the program will do everything for ya.\n");
  printf("Number: ");
  scanf("%d", &number);

  // start recursion.
  numbers(number);
  printf("\n");
}

void numbers(int n){
    if (n == 0)
        return;
    numbers(n-1);

    // after return from recursion
    printf("%d ", n);
}

答案 1 :(得分:1)

如评论中所述,您的实现不会停止计数,因为它不知道目标值是多少。例如,如果用户输入“ 2”,则代码将运行numbers(0),返回0,然后运行numbers(1),返回1,然后运行numbers(2),调用{{1} }等,直到堆栈空间不足为止。

根据我对问题的理解,以下内容应该起作用。

numbers(3)

我将打印移到了递归函数中,因为它可以更轻松地输出每个数字(并智能地打印数字之间的逗号),而使用递归函数和一个void count(int from, int to) { printf( "%d", from ); if( from < to ) { printf( ", "); count( from+1, to ); } } int main(int argc, char const *argv[]) { int number; printf("Put a number and the program will do everything for ya.\n"); printf("Number: "); scanf("%d", &number); count(1,number); } 循环进行计数。

该函数仅打印出当前值,然后检查其是否已达到目标。如果不是,则递归地计算到下一个数字。

答案 2 :(得分:0)

如果您发送的数字> = 2,例如,如果我向您的数字函数发送2,则您的递归永远不会结束,下一个调用步骤是3,下一个是4、5、6等。 / p>

正确的代码是:

int main(int argc, char const *argv[]) {

  int number;
  int i;

  printf("Put a number and the program will do everything for ya.\n");
  printf("Number: ");
  scanf("%d", &number);
  for(i=0;i<=number;i++){
    printf("%d, ", i);
}

如果您想进行递归,则可以进行倒计时,从而为递归提供更多的帮助

int main(int argc, char const *argv[]) {

  int number;

  printf("Put a number and the program will do everything for ya.\n");
  printf("Number: ");
  scanf("%d", &number);
  numbers(number);
}

void numbers(int n)
{
  printf("%d, ", n);
  if (n > 0)
    numbers(n - 1);
}

答案 3 :(得分:0)

在这种情况下,由于我们没有要分配的目标值,因此堆栈用完了空间,因此我们知道要调用多少时间递归函数。