两个模拟atoi的C函数差异解析:为何后者忽略后续字符
两个模拟
atoi函数的行为差异分析 我实现了两个模拟C标准库<stdlib.h>中atoi函数的C语言函数,在传入测试字符串时表现出截然不同的结果,以下是具体分析:
第一个函数实现及行为
int _atoi(char *s) { int i, neg = 1, n = 0; for (i = 0; s[i] != '\0'; i++) { if ((s[i] >= '0') && (s[i] <= '9')) n = n * 10 + (s[i] - '0'); else if (s[i] == '-') neg *= -1; } n *= neg; return (n); }
当传入字符串" + + - -98 Battery Street; San Francisco, CA 94111 - USA "时,该函数返回结果为-9894111。
第二个函数实现及行为
int _atoi(char *s) { int sign = 1, i = 0, res = 0; while (!(s[i] <= '9' && s[i] >= '0') && s[i] != '\0') { if (s[i] == '-') sign *= -1; i++; } while (s[i] <= '9' && s[i] >= '0' && s[i] != '\0') { res = (res * 10) + (s[i] - '0'); i++; } res *= sign; return (res); }
调用该函数时返回结果为98,与标准atoi函数的返回值一致。
两者的核心差异及结果原因
第一个函数的逻辑
该函数会遍历字符串的每一个字符直到结束:
- 只要遇到数字字符,就直接将其累加到结果中,不管数字出现在字符串的哪个位置
- 遇到
'-'字符时,就反转一次符号标记
因此测试字符串中所有的数字(98和94111)都会被累加为9894111,而所有的'-'(共3个)会让符号标记最终为-1,最终返回-9894111。
第二个函数的逻辑
该函数采用分阶段处理的逻辑,完全贴合标准atoi的行为:
- 第一阶段:跳过所有非数字的前置字符,同时在这些前置字符中处理
'-'来确定符号,遇到一个'-'就反转一次符号 - 第二阶段:只处理从第一个数字开始的连续数字字符,一旦遇到非数字字符(比如
98后面的空格),就立即停止遍历,后续的所有字符(包括94111和后面的'-')都不会被处理
因此,第二个函数只会处理98这两个连续数字,而前置的两个'-'让符号标记最终为1(负负得正),所以返回98,和标准atoi的行为一致。
核心差异总结
- 第一个函数不区分数字出现的位置,会处理字符串中所有的数字和
'-' - 第二个函数只处理第一个连续数字段,前置非数字中的
'-'仅用来确定符号,数字段结束后就停止处理后续内容
内容的提问来源于stack exchange,提问作者Bane
相关产品推荐
相关产品推荐

