一. 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; }
以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏
希望大佬们看到错误之后能够不吝赐教 在评论区或者私信指正 博主一定及时修正
那么大家下期再见咯