了解 atoi() 函数
Posted
技术标签:
【中文标题】了解 atoi() 函数【英文标题】:Understanding an atoi() function 【发布时间】:2011-10-31 17:50:44 【问题描述】:我是一名 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,那么函数的其余部分如何工作? 我可能把我的基础知识都搞砸了,但任何帮助都将不胜感激。谢谢,-克雷格
【问题讨论】:
我不知道 C 是那可怕的。 我认为理解一段代码最好的方法是用调试器(例如gdb)执行它,然后一步一步往前走。阅读代码和里面的 cmets 也可能会有所帮助。 @PatrickB.: 那是 非常古老的 C. 现代 C 看起来...完全一样 :) (除了现在更清晰的函数签名int atoi(const char * s)
.)
在 K&R 的第 2 版中,该函数具有更好(和更现代)的风格......请参见此处:codepad.org/U4hPr4Eg
@PatrickB。 C 是一个跨平台的汇编程序,仅此而已……按照今天的标准(除了其影响和使用的激进范围之外),它没有什么令人兴奋的。但不要将它与 C++11 之类的东西混为一谈,对于那些有耐心学习它的人来说,C++11 是一种深刻的范式转换野兽。
【参考方案1】:
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) 将指针设置在 char 数组的开头
2) 然后在 while 循环中遍历每个字符并乘以 10,然后通过减去 0 来添加字符。
如果您尝试使用 2992,那么数字也将是 2992。
【讨论】:
如果 OP 回到了 K&R,那么我会指出,在 C89 中,你不能将声明放在代码中间:***.com/questions/288441/…【参考方案2】:第一个循环执行注释所说的:它跳过空格。
在它之后,i
是第一个非空白字符的索引,这正是您需要继续进行的。
【讨论】:
【参考方案3】:不,第一个循环跳过空格,就像评论说的那样。
【讨论】:
【参考方案4】:评论提供了答案:第一个循环是跳过空格。对于2992
,i
将保留为0
。
【讨论】:
【参考方案5】:第一个 for 循环推进 i 指向第一个非空白字符。
循环之间的条件会记下符号,如果有的话。
然后最后的 for 循环进行实际的转换。
最后,应用符号,并返回结果。
【讨论】:
【参考方案6】:1) 没有第一个 for 循环不计算字符数,但如果只有起始字符是空格,它会计算数字的第一个位置,即对于这个“-2992”,我将是 1,对于“2992”,我将是 0 .
2) sign = (s[i++] == '+') ? 1 : -1;
此语句检查第 i 个字符是否为符号并使计数器升高 1[i++] 并且对于下一个 for 循环,此 i 是字符串中的第一个起始数字。如果我为 0,那么对于第一个条件输入,您的检查章程将是空格!
edit1:第一个输入是“space space-2992”
【讨论】:
以上是关于了解 atoi() 函数的主要内容,如果未能解决你的问题,请参考以下文章