理解atoi()函数

8

我是一名Python程序员,正在学习K&R的C语言书籍。这可能看起来是一个非常琐碎的问题,但我还是感到困惑。 下面附上K&R(RIP Ritchie!)书中实现atoi()函数的代码片段。

atoi(s) /*convert s to integer */
char s[];
{
    int i, n, sign;
    for (i=0; s[i]==' '||s[i] == '\n' || s[i] == '\t'; i++)
    ;   /* skip whitespace */
    sign = 1;
    if (s[i] == '+' || s[i] = '-')  /* sign */
        sign = (s[i++] == '+') ? 1 : -1;
    for (n=0; s[i] >= '0' && s[i] <= '9'; i++)
        n = 10 * n + s[i] - '0';
    return (sign * n);
}

我的问题:

1)除了计算有效字符的数量之外,第一个“for”循环还有其他作用吗?
2)如果(1)是真的,第一个循环将'i'的值设置为有效字符的数量 - 第二个for循环如何在不重置i为0的情况下工作?

举个例子,如果我输入“2992”到这个函数中。第一个for循环将i设置为3,那么这个函数的其余部分如何工作? 我可能把基础知识搞混了,但任何帮助都将不胜感激。谢谢,-Craig


1
我不知道C语言会这么糟糕。 - Patrick B.
我认为理解一段代码的最佳方式是使用调试器(例如gdb)逐步执行。同时阅读代码和内部注释也可能有所帮助。 - eyalm
@PatrickB.:那是非常老的C语言。现代的C语言看起来...完全一样 :)(除了函数签名,现在更清晰的是int atoi(const char * s)。) - Mat
在K&R的第二版中,该函数具有更好(且更现代)的风格...请参见此处:http://codepad.org/U4hPr4Eg - pmg
@PatrickB。C是一种跨平台汇编语言,除了其影响和使用的激进范围外,在今天的标准下没有什么惊人之处。但不要将其与像C++11这样的语言混淆,对于那些有耐心学习它的人来说,它是一种深刻的范式转换工具。 - HostileFork says dont trust SE
6个回答

11
int atoi(char* str)
{
    if(!str)
        printf("Enter valid string");

    int number = 0;
    char* p = str;

    while((*p >= '0') && (*p <= '9'))
    {
        number = number * 10 + (*p - '0');
        p++;
    } 
    return number;
}

ATOI的整个思想如下:

1)将指针设置在字符数组的开头

2)然后在while循环内遍历每个字符,乘以10并通过减去0来添加字符。

如果您尝试使用2992,则数字也将为2992。


如果 OP 要回到 K&R,那我要指出在 C89 中你不能将声明放在代码中间:https://dev59.com/DHVC5IYBdhLWcg3wcw0m - HostileFork says dont trust SE

4
第一个循环执行注释中的操作:跳过空白字符。
在此之后,i 是第一个非空白字符的索引,这正是您需要继续的内容。

1
不,第一个循环会跳过空格,就像注释所说的那样。

1

这个注释提供了答案:第一个循环是为了跳过空格。对于2992i将保持为0


1

第一个for循环将i推进到指向第一个非空格字符。

循环之间的条件记录了符号(如果有)。

然后最后一个for循环执行实际的转换。

最后,应用符号,并返回结果。


0

1) 第一个for循环不计算字符数,而是计算数字的第一个位置,如果只有起始字符是空格,例如对于“-2992”,i将为1,而对于“2992”,i将为0。 2)sign = (s[i++] == '+') ? 1 : -1; 这个语句检查第i个字符是否为符号,并使计数器加1 [i ++],对于下一个for循环,这个i是字符串中第一个起始数字。如果i变成0,则对于第一个条件输入,您要检查的字符将是空格!

编辑1:第一个输入是“空格空格-2992”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接