C中递归函数的错误输出

时间:2014-12-24 08:49:02

标签: c visual-studio-2012 recursion

我应该创建一个递归函数,使用putchar()而不是printf来逐位打印整数。输出应该是1234但我得到1234(笑脸)1234。为什么会这样?

另外,你能添加一个' \ n'在printf之外?

非常感谢。

#include <stdio.h>

int printnumber();

int main()
{
    int n = 1234;
    printnumber(n);
    return 0; 
}

int printnumber(int n) {
    int x, y;
    x = flip(n) % 10;
    putchar(x);
    y = flip(n) / 10;
    if (y < 0)
        printnumber(y);
}

int flip(int n)
{
    if (n < 0) {
        putchar('-');
        n = -n;
    }
    if (n / 10)
        flip(n / 10);
    putchar(n % 10 + '0');
}

8 个答案:

答案 0 :(得分:2)

您的代码具有未定义的行为,因为声明为返回类型int的函数翻转实际上不会返回任何内容。

似乎功能翻转完成所有工作。所以不清楚函数printnumber是什么意思。

您可以按照以下方式定义功能

#include <stdio.h>

void print_number( int n )
{
    if ( n < 0 ) 
    {
        putchar('-');
        n = -n;
    }

    if ( n / 10 ) print_number( n / 10 );
    putchar( n % 10 + '0' );
}

int main(void) 
{
    print_number( -1234 );


    return 0;
}

输出

-1234

答案 1 :(得分:1)

在您的代码中,

x = flip(n) % 10;

Line调用未定义的行为。

return没有int flip(int n)任何值。因此,在执行上述步骤时,编译器将没有来自flip(n)调用的显式返回值,因此结果是未定义的。

相关阅读: 来自C99规范文档,第6.9.1章第12段

  

如果到达终止函数的},则使用函数调用的值   调用者,行为未定义。

注意:想一个更简单的逻辑。这是用于打印数字的 overkill

答案 2 :(得分:1)

该代码看起来太复杂了。这是我的单功能版本:

void printNumber(int n) {
    if (n < 0) {
        putchar('-');
        printNumber(-n);
    } else {
        if (n >= 10) {
            printNumber(n / 10);
        }
        putchar('0' + (n % 10));
    }
}

即。输出-并递归负数,否则使用反向递归(以便数字以正确的顺序出现)首先递归调用自己最左边的数字,然后打印最右边的数字。

也可以使用标准div函数来避免单独的除法和模数运算,该函数在一个步骤中产生两者,尽管这是否更有效取决于实现。

void printNumber(int n) {
    if (n < 0) {
        putchar('-');
        printNumber(-n);
    } else {
        div_t d = div(n, 10);
        if (d.quot) {
            printNumber(d.quot);
        }
        putchar('0' + d.rem);
    }
}

答案 3 :(得分:0)

假设这是你打算做的。在使用递归函数时,递归函数调用之后的行被压入堆栈,因此我们可以使用它并打印1234,如下所示。

#include <stdio.h>

void printnumber();

int main()
{
    int n = 1234;
    printnumber(n);
    return 0; 
}

void printnumber(int n) {
    char ch;
    int x;
    if(n == 0)
    return;
    else
    {
       x = n % 10;
       n = n/10;
       ch = x + '0';
       printnumber(n);
       putchar(ch);
    }
}

答案 4 :(得分:0)

是否需要flip()函数?你可以看一下......

#include <stdio.h>

void printnumber(int n);

int main()
{
    int n = -1234;
    printnumber(n);
    return 0;
}

void printnumber(int n) {
    if(n/10==0)
    {
        if(n<0)
        {
            putchar('-');
            n=-n;
        }
        putchar(n+'0');
        return;
    }
    int x, y;
    x=n%10;
    if(x<0)
    x=-x;
    printnumber(n/10);
    putchar(x+'0');
}

答案 5 :(得分:0)

我假设你想要:

  • 一个带int和displayint的函数
  • 调用递归函数逐位打印
  • display在数字
  • 后面添加一个新行(\n

但是由于你的函数没有返回任何感兴趣的东西,最好将它们声明为void。它可以避免在没有任何返回的情况下使用函数值的未定义行为(printnumber中为x = flip(n) % 10;

你可以这样做:

#include <stdio.h>

/* function declaration before usage */
void flip(int n);
void printnumber(int n)

int main()
{
    int n = 1234;
    printnumber(n);
    return 0; 
}

/* prints a int followed by new line */
void printnumber(int n) {
    if (n < 0) {
        putchar('-');
        n = -n;
    }
    flip(n);
    putchar('\n');
}

/* recursively prints decimal digits of an int */
void flip(int n)
{
    if (n / 10)
        flip(n / 10);
    putchar(n % 10 + '0');
}

每条评论编辑:如果你只想要一个函数,你应该更好地将主要内容放在一次:

#include <stdio.h>

/* function declaration before usage */
void printnumber(int n)

int main()
{
    int n = 1234;
    if (n < 0) {
        putchar('-');
        n = -n;
    }
    printnumber(n);
    putchar('\n');
    return 0; 
}

/* recursively prints decimal digits of an int */
void printnumber(int n)
{
    if (n / 10)
        printnumber(n / 10);
    putchar(n % 10 + '0');
}

答案 6 :(得分:0)

首先回答您更简单的问题,您可以使用putchar('\n')输出换行符。 printf只是反复调用putchar。

你的代码有点过于复杂,除了别的以外,flip()还没有返回一个值(总是打开编译器警告 - 他们告诉你什么时候做某些傻事(或危险))

实现将是这样的:

#inclde <stdio.h>

void print_digits(unsigned n)
{
    if (n >= 10) { print_digits(n / 10); }
    putchar(n % 10 + '0');
}

void printnumber(int n)
{
    /* Copes with max negative integer */
    unsigned u = n;
    if (n < 0) { putchar('-'); u = -u; }
    print_digits(u);
}

int main(void)
{
    int n = 1234;
    print_number(n);
    putchar('\n');
    return 0;
}

答案 7 :(得分:0)

两个问题

  1. 使用int flip()的返回值,但未能提供返回值的函数调用未定义的行为(UB) - 任何事情都可能发生。 @Sourav Ghosh

  2. n = -n;也是一个利基问题。当许多系统上n == INT_MIN使用2的补码整数时,结果也是UB。为了解决这个问题,否定正数并用负数递归。使用int时,负数范围始终至少或大于正数范围。

  3. 使用另一个'\n'将<{1}}添加到printf之外。

    putchar()

    输出

    #include <limits.h>
    #include <stdio.h>
    
    static void printdigit(int n) {
      if (n <= -10) {
        printdigit(n / 10);
      }
      putchar('0' - n % 10);  // use -
    }
    
    void printnumber(int n) {
      if (n < 0) {
        putchar('-');
      } else {
        n = -n;
      }
      printdigit(n);
      putchar('\n');
    }
    int main(void) {
      printnumber(1234);
      printnumber(-1234);
      printnumber(INT_MIN);
      printnumber(INT_MAX);
      printnumber(0);
      return 0;
    }