递归数字函数返回意外值

时间:2012-12-26 02:22:06

标签: c string recursion int

在广泛搜索一个可以将整数转换为视觉上等效的字符串并且什么都没找到的函数后,我决定编写自己的函数。

功能" ascii"有三个参数:要转换的整数,用于保存转换整数的字符串,以及要保留为0的计数器。

void ascii(int c, char str[], int k) {
    if (c <= 9) {
        str[k] = c + '0';
    }

    else if (c >= 10) {
        str[k] = c / 10 + '0';
        ascii(c % 10, str, k + 1);
    }
}

使用一位数字测试此功能不会出现任何意外情况,但是对于更大的数字,事情开始变得混乱。 76变为&#34; 761&#34;,765变为&#34; | 51&#34;,并且7658变为&#34; -81&#34;。数字组成的位数越多,我对结果字符串的理解就越少。是什么给了什么?

4 个答案:

答案 0 :(得分:3)

我相信这是问题所在:

else if (c >= 10) {
    str[k] = c % 10 + 48;
    ascii(c / 10, str, k + 1);
}

算术运算被反转。之后必须反转生成的数组(来自不同的函数,它将问题中的函数作为帮助程序调用),并且必须以'\0' char结尾。

或者,你可以按相反的顺序复制输出数组中的结果,但假设你事先知道了数字位数。

答案 1 :(得分:1)

对于案例c = 123,您实际上是这样做的:

    str[k] = 12 + '0';
    ascii(3, str, k + 1);

我不确定你打算发生什么,但这可能不是你的意思。

答案 2 :(得分:0)

其他答案指出了最重要的错误 - 你交换了模数和除法;仍然,即使进行了修正,生成的字符串也会被反转,因为使用模数可以快速得到最不重要的数字,它应该向右移动,但是你把它放在左边,因为在开头是未知的最后长度字符串。

您可以反转此字符串,使用对数查找位数或使用其他递归方法:

void ascii(int c, char str[])
{
    if(c<0)
    {
        *(str++)='-';
        c=-c;
    }
    *(ascii_helper(c, str))='\0';
}

char * ascii_helper(int c, char str[])
{
    if (c > 9)
        str=ascii_helper(c/10, str);
    *str = c%10 + '0';
    return str+1;
}

这通过推迟实际写入数字直到其位置已知为止。递归继续进行,直到找到最重要的数字,然后每个调用向其调用者返回下一个字符的位置,该字符用于正确定位每个数字。请注意,此函数不能像原始函数那样进行尾部优化,因此它的空间效率较低(尽管这种情况大多无关紧要,因为int无论如何通常不能超过20位数。)

答案 3 :(得分:0)

  • 首先你交换了模数和除法,这就是你得到那些意想不到的答案的原因。
  • 此外,这给出了你所期待的反向答案。所以要重新编号,然后尝试解决它。​​

    void ascii(int c, char str[], int k) {
    /*first let us reverse the string
    because recursive solution will be reverse of our expected solution*/
    int r=0,i;
    for(i=c;i>0;i=i/10)
    r=r*10+i%10;
    
    if (r <= 9) {
        str[k] = r + '0';
    
    }
    else if (r >= 10) {
         ascii(r / 10, str, k+1 );
         str[k] = r%10 + '0';
    }
    return;
    }
    
相关问题