C 将字符串递归转换为整数?

C 将字符串递归转换为整数?,c,recursion,C,Recursion,下面是一个将字符串转换为整数的简单函数 int str2int(char *str) { int ret = 0; char *c; for (c = str; (*c != '\0') && isdigit(*c); ++c) ret = ret*10 + *c - '0'; return ret; } 作为练习,我想写一个递归函数来做同样的事情。这就是我想到的 int str2int2(char *c, int *i) {

下面是一个将字符串转换为整数的简单函数

int str2int(char *str)
{
    int ret = 0;
    char *c;

    for (c = str; (*c != '\0') && isdigit(*c); ++c)
        ret = ret*10 + *c - '0';

    return ret;
}
作为练习,我想写一个递归函数来做同样的事情。这就是我想到的

int str2int2(char *c, int *i)
{
    if (*c == '\0' || !isdigit(*c))
        return *i;

    *i = *i * 10 + *c - '0';

    return str2int2(c + 1, i);
}

.
.
int i = 0;
.
... str2int2(str, &i);
有没有一种不使用额外的
int*
参数编写递归函数的方法?

我认为您可以使用,以避免保留任何“I”

您必须反转字符串(是的),然后您可以简单地使用:

int str2int (char* str)
{
    if (*str+1)
    {
        return 10*str2int(str+1)+(*str-'0');
    }
    return 0;
}
我想你可以使用,以免保留任何“我”

您必须反转字符串(是的),然后您可以简单地使用:

int str2int (char* str)
{
    if (*str+1)
    {
        return 10*str2int(str+1)+(*str-'0');
    }
    return 0;
}

那么,您可以对使用该功能的人隐藏该功能。因此,您将有一个名为
intstr2int(char*str)
的函数,此后将调用
intstr2int(char*c,int*i)


这是我过去的做法。

好吧,你可以对使用该功能的人隐藏该功能。因此,您将有一个名为
intstr2int(char*str)
的函数,此后将调用
intstr2int(char*c,int*i)


这是我过去的做法。

当然,这很简单,但您需要编写两个函数,一个带有累加器,如下所示:

int str2int_rec(char *c, int accum)
{
    if (!c || !*c || !isdigit(*c))
        return accum;

    return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}

int str2int(char *c)
{
    return str2int_rec(c, 0);
}
int i = strtoi("432", 3);

当然,这很简单,但您需要编写两个函数,一个带有累加器,如下所示:

int str2int_rec(char *c, int accum)
{
    if (!c || !*c || !isdigit(*c))
        return accum;

    return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}

int str2int(char *c)
{
    return str2int_rec(c, 0);
}
int i = strtoi("432", 3);

一种方法可能涉及将数字的长度作为参数传递,以便我们能够高效地向后读取:

int strtoi(char *c, size_t l)
{
    return l ? c[l-1] - '0' + 10 * strtoi(c, l - 1) : 0;
}
那么就这样称呼它:

int str2int_rec(char *c, int accum)
{
    if (!c || !*c || !isdigit(*c))
        return accum;

    return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}

int str2int(char *c)
{
    return str2int_rec(c, 0);
}
int i = strtoi("432", 3);
或:

但这并不总是最佳的麻烦与长度的字符串。另外,如果一个字符串的数字后面有字符,我们必须手动将其考虑进去,因为这个函数不会为我们做这件事。我们不能(不应该)在函数中使用
strlen()
来避免传递参数,因为这会导致每次重新计算字符串长度的速度大大降低。当然,从一开始就必须有办法做到这一点,即使我们不得不动用重炮:

int strtoi(char *c)
{
    if(!isdigit(*c)) return 0;
    int i = strtoi(c + 1);
    return i + pow(10, (int)(log(i + 1)/log(10)) + (i != 0)) * (*c - '0');
}
不,这个
(int)
cast不是可选的。基本上,所有这些数学运算都是根据上一次递归调用返回的数字,计算出当前数字乘以10的幂


我知道这可能是一个学习练习,但递归并不是编程的全部目的。在某些语言中,对于某些任务,包括我自己在内的一些人会称之为美丽,但从外观上看,这不属于这种情况。

一种方法可能涉及将数字的长度作为参数传递,以便我们能够高效地向后阅读:

int strtoi(char *c, size_t l)
{
    return l ? c[l-1] - '0' + 10 * strtoi(c, l - 1) : 0;
}
那么就这样称呼它:

int str2int_rec(char *c, int accum)
{
    if (!c || !*c || !isdigit(*c))
        return accum;

    return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}

int str2int(char *c)
{
    return str2int_rec(c, 0);
}
int i = strtoi("432", 3);
或:

但这并不总是最佳的麻烦与长度的字符串。另外,如果一个字符串的数字后面有字符,我们必须手动将其考虑进去,因为这个函数不会为我们做这件事。我们不能(不应该)在函数中使用
strlen()
来避免传递参数,因为这会导致每次重新计算字符串长度的速度大大降低。当然,从一开始就必须有办法做到这一点,即使我们不得不动用重炮:

int strtoi(char *c)
{
    if(!isdigit(*c)) return 0;
    int i = strtoi(c + 1);
    return i + pow(10, (int)(log(i + 1)/log(10)) + (i != 0)) * (*c - '0');
}
不,这个
(int)
cast不是可选的。基本上,所有这些数学运算都是根据上一次递归调用返回的数字,计算出当前数字乘以10的幂


我知道这可能是一个学习练习,但递归并不是编程的全部目的。在某些语言中,对于某些任务,包括我在内的一些人会称之为“美丽”,但从外观上看,这不属于这些情况。

我认为你的意思是“反转”而不是“还原”是的,更正了。谢谢:)(英语不是我的母语)这里的一个问题是,当你反转字符串时,你必须在结尾保留空字节。也许这不是不可能的,但肯定是个麻烦。@Chris:可能会有问题,但我认为他想要的是一个优雅的解决方案,而不是一个“有效”的解决方案。我想你的意思是“反向”而不是“回复”是的,更正了。谢谢:)(英语不是我的母语)这里的一个问题是,当你反转字符串时,你必须在结尾保留空字节。也许这不是不可能的,但肯定是个麻烦。@Chris:可能会有问题,但我认为他想要的是一个优雅的解决方案,而不是一个“有效”的解决方案。你应该展示如何做到这一点,而不是仅仅概述问题。这比你从简洁的“答案”中想象的要复杂得多。很抱歉,我本以为它很简单,就是从一个新的方法调用这个方法,如上面接受的答案所示。我发现我所谓的“答案”与答案相差不远,除了实际的示例代码。你应该展示如何做到这一点,而不仅仅是概述问题。这比你从简洁的“答案”中想象的要复杂得多。很抱歉,我本以为它很简单,就是从一个新的方法调用这个方法,如上面接受的答案所示。我发现我所谓的“答案”与答案相差不远,除了实际的示例代码。这不是严格必要的,但肯定要干净得多。这是你应该使用的实际答案,与我的答案相比,这简直是荒谬可笑+1还请注意,str2int_rec函数是尾部递归函数,这意味着编译器可能会像原始命令代码一样将其简化为循环。+1我完全弄糟了str2int()函数的累加器部分。严格来说,这不是必需的,但肯定要干净得多。这是你应该使用的实际答案,与我的答案相比,这简直是荒谬可笑+1还请注意,str2int_rec函数是尾部递归函数,这意味着编译器可能会像原始命令代码一样将其简化为循环。+1我完全弄糟了str2int()函数的累加器部分。除了pow函数可能很昂贵(而(power--)result*=result;)。。