面试官特别喜欢让你仿写一个库里面的函数。atoi就是频率很高的一个。
atoi的函数原型是 int aoti(const int *nptr),其实现在stdlib.h头文件中。
现在我们来分析并仿写一下atoi函数的具体实现。
仿写某一个库函数的步骤如下:
- 先使用库中的函数进行测试,将所有可能的测试用例进行输入,并观察结果。这是模仿黑盒测试,你不知道源码,只能从功能上来进行分析。
- 再其次设计一下函数的框架,包括函数的返回值类型和函数的参数列表
- 最后按自己的逻辑进行编写,然后再测试,是否达到了和库中一样的效果。特别要注意的是,边界条件的测试,这点很关键也很重要
1.对于含有多个空格的字符串,atoi会帮我们去除掉空格
2.然后只允许在字符串的起始字符处出现符号,后面再出现就直接返回0
3.如果字符串中间出现了非数字字符,那么转换就此终止。返回前面的值
4.大数,超过int可以表示的范围了,即不在-INT_MAX-1 ~ INT_MAX范围内,如果是负数,直接返回-INT_MAX-1 ,如果是正数返回INT_MAX
#include
#include
using namespace std;
int myatoi(const char* str)
{
if (nullptr == str)
{
return 0;
}
int flag = 1;//存储正负号
int res=0;
//先处理遇到的空格和符号
while (*str == ' ')
{
str++;
}
//再处理遇到的第一个符号
if (*str == '-')
{
flag = -1;
str++;
}
else if (*str == '+')
{
flag = 1;
str++;
}
else if (*str< '0'&& *str > '9')//第一个字符就是非数字类型的字符,那么立马返回
{
return 0;
}
//此后如果还遇到非数字字符,则直接退出循环,保存遇到非数字字符之前的值。
while (*str != '\0' && *str >= '0' && *str <= '9')//如果还是在后面遇到非数字字符就不满足循环条件了
{
res = res * 10 + *str - '0';
if (res < 0)
{
res = INT_MAX; //处理大数的情况,超出了int的表示范围。则一定会变号
break;
}
str++;
}
return (flag == -1 )? -res - 1 : res;
}
int main()
{
int a = 0;
const char* p = "-b123a45";
const char* p2 = " 123456789123456789";//超出int表示范围的测试用例
const char* p5 = "-2147483649";
const char* p3 = " +123466";
const char* p4 = " -234a5";
a = myatoi(p5);
//a = atoi(p5);
cout << a << endl;
return 0;
}