atoi函数的初步实现到完美优化
aoti函数的初步实现到完美优化
- 一. atoi函数简介
- 二. 简单实现
- 三. 面试官的压力测试
- 四. 完美优化
- 4.1 空指针解决
- 4.2 字符串为空
- 4.3 字符串前面为空
- 4.4 正负号
- 4.5 非数字字符
- 4.6 越界问题
- 4.7 最后检查
- 五 完整代码加试运行
一. atoi函数简介
aoti把字符串转化成整型的一个函数
先看怎么使用
传入一个字符类型的指针 变成一个整型的数据
话不多说 咱直接上代码
int main()
{
char arr[20] = "1234";
int a = atoi(arr);
printf("%d", a);
return 0;
}
代码演示的效果如下
二. 简单实现
现在同学们大概了解了atoi这个函数怎么使用了吧
我们先来看看大概怎么实现这个函数
我们大概用代码来实现一下
int my_atoi(char* str)
{
int n = 0;
while (*str)
{
n = n * 10 + (*str - '0');
str++;
}
return n;
}
我们来看看效果
能跑
但是! 如果你再面试的时候 回答这个实现方式的话 你很可能就要接受面试官的
压力测试了!
三. 面试官的压力测试
面试官: 我觉得你刚刚这个实现想法很好 但是你有没有考虑过这样子的情
况呢?
如果传入的是空指针怎么办呢?
如果传入的是空字符串怎么办呢?
如果传入的是非数字字符怎么办呢?
如果前面有空白字符怎么办呢?
如果前面有正负号怎么办呢?
除了我上面的说的那些问题是否还存在其他的问题呢?
这些你刚刚写的函数可以解决吗?
我: 鹅 我知道你很急 但是你先听我说
你先别急
我们这样来优化
四. 完美优化
4.1 空指针解决
首先 空指针的问题是我们最不能容忍的 这时候我们需要先断言一下
assert(str);
在键盘上轻轻的敲上这一行代码 空指针的问题就被我们解决啦
4.2 字符串为空
如果传入的是一个空字符串的话 判断起来很简单
第一个字符就是\0
if (*str=='\0')
{
return 0;
}
那么 如果我们判断到了是空字符串 我们返回什么呢?
仔细一想 好像返回什么都不合适
那么我们这里做这样一件事
**我们枚举两个变量 合法 和 非法 **
因为很多输出都是非法操作
所以首先将状态设为非法
代码表示如下
enum Status
{
VALUD,
INVALUD
};
enum Status status = INVALUD;
4.3 字符串前面为空
如果 我们发现一个字符串的前面是空白字符 那么我们只需要将它跳过去就可
以了 这里有两种解法
while (*str==' ')
{
str++;
}
4.4 正负号
这个也很简单
我们可以设置一个记号标志 flag
我们在遍历前面的时候 如果遍历到正号 falg就赋值为1
如果遍历到负号 falg就赋值为-1
如果什么符号都没有 那就默认是正数
所以说我们将flag的初始值赋值为1
// 正负号
if (*str =='+')
{
flag = 1;
str++;
}
else if (*str=='-')
{
flag = -1;
str++;
}
4.5 非数字字符
这里我们遍历字符串 如果遍历到非数字字符 其实再遍历下去也没有什么意义
了
所以说 我们遇到非数字字符就停止遍历 抛出异常
while (isdigit( * str))
{
n = n * 10 + (flag)*(*str - '0');
str++;
}
4.6 越界问题
如果说 n比最小值还小 比最大值还大 那就说明数字可能越界了
这里我们也需要抛出异常
但是这里我们不能使用int类型的n来存储了
否则它就会发生截断 从而不会抛出异常
所以说 我们将 n的类型定义为 long long
if (n<INT_MIN || n>INT_MAX)
{
n = 0;
break;
}
4.7 最后检查
最后 如果说上面的错误一个都没有发生 很顺利的进行到程序的最下面了
那么我们可以在程序的最后面将状态改为合法
if (*str=='\0')
{
status = VALUD;
}
五 完整代码加试运行
优化完成之后我们邪魅一笑
将源码甩给面试官
enum Status
{
VALUD,
INVALUD
};
enum Status status = INVALUD;
int my_atoi(char* str)
{
long long n = 0;
int flag = 1;
assert(str);
//字符串为空
if (*str=='\0')
{
return 0;
}
//字符串前面为空
//while (*str==' ')
//{
// str++;
//}
while (isspace(*str))
{
str++;
}
// 正负号
if (*str =='+')
{
flag = 1;
str++;
}
else if (*str=='-')
{
flag = -1;
str++;
}
while (*str !='\0')
{
if (isdigit(*str))
{
n = n * 10 + (flag) * (*str - '0');
if (n<INT_MIN || n>INT_MAX)
{
n = 0;
break;
}
str++;
}
else
{
break;
}
}
if (*str=='\0')
{
status = VALUD;
}
return n;
}
int main()
{
char arr[20] = "12a34";
int num = my_atoi(arr);
if (status==VALUD)
{
printf("%d ", num);
}
else if (status==INVALUD)
{
printf("非法数字%d ", num);
}
return 0;
}
以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏
希望大佬们看到错误之后能够不吝赐教 在评论区或者私信指正 博主一定及时修正
那么大家下期再见咯