首页 > 解决方案 > 在尝试编写 atoi 的递归版本时,itoa(n /10, s) 的含义是什么,为什么建议避免使用 static int i = 0?

问题描述

如果我的问题很模糊,我很抱歉,因为它没有上下文。所以我试图解决一个问题:编写函数 itoa(i) 的递归版本,它将整数 i 转换为字符串。

当我不知道如何解决它时,我开始在网上寻找解决方案,我遇到了一些通常使用这条线的解决方案:itoa(n/10, s);。例如,来自这个 StackOverflow 问题:itoa recursively。我无法理解它对我有什么影响。

所以我继续寻找更多解决方案,我找到了一个真正有效的解决方案,程序如下所示:

#include <stdio.h>

char *itoa(int n, char s[]);

int main()
{
    char number[100];

    printf("-90 to string = %s\n", itoa(-90, number));

    return 0;
}

char *itoa(int n, char s[])
{
    static int i = 0;

    if (n < 0) {
        s[i++] = '-';
        n = -n; /* does not work for largest negative number in two complement */
    }

    if (n / 10)
        itoa(n /10, s);

    s[i++] = n % 10 + '0';
    s[i] = '\0';

    return s;
}

问题是,根据我在其他网站上找到的解决方案,人们说我们应该避免使用静态 int i。我没有读到为什么我们应该这样做,因为我不知道静态是如何工作的,所以我不知道这个程序是否很好或需要改进。

标签: crecursion

解决方案


您的功能几乎是正确的,即用于递归方法。如果您要将数字向后解析为字符串,那是对的。否则,我只是做了几个修复。

对于将数字解析为字符串,正在解析的数字是从右数到左数,因为其余的是正在使用的数字。因此,当将它们存储到字符串中时,我们需要从高索引到低索引。如果我们使用余数进行解析,我们将不知道正在解析的数字的长度。因此,在大多数解析情况下,字符串或字符数组的开头会有一些额外的空格。

对于使用静态 i,您可以传递它的一个版本,但它会使其更难使用,因为您需要知道始终必须在 11 处传递 i。“i”位于 11,因为 int 的最大位数是 10(digits) + 1 符号,第 12 个不被“i”计算的字符是空字符。为了使函数更容易使用,我将第三个参数配置为空指针。但是,不要将实际指针传递给它,而是将其传递给 NULL。当它看到 NULL 作为第三个参数时,它就知道,那是第一次调用。

#include <stdio.h>
#include <string.h>
char *itoa(int n, char s[], void * );

int main()
{
    char number[100] = {0};

    printf("-90 to string = %s\n", itoa(154, number, NULL));
    printf("-15 to string = %s\n", itoa(-15, number, NULL));
    printf("-2147483648 to string = %s\n", itoa(-2147483648, number, NULL));

    return 0;
}

// The reason why I pass a void pointer is because
// instead of passing the value is because it easier to use function without needing to know that the string have to go from right left.
// When you first call it just use NULL as the third parameter. Anything else can ruin it.
char *itoa(int n, char s[], void * firstCall )
{
    static int i;
    if ( firstCall == NULL ) {
        i = 11;
        s[11] = 0;
    }

    int neg = 0;

    if (n < 0) {
        if ( n == -2147483648 ) {

          strcpy(s, "-2147483648");
          return s;
        }
        neg=1;
        n = -n; /* does not work for largest negative number in two complement */
    } 

    s[--i] = (n % 10) ^ 48;

    if ( n / 10 ) itoa(n / 10, s, s);

    if ( neg == 1 ) s[--i] = '-';

    return &s[i];
}

推荐阅读