atoi函数的初步实现到完美优化

简介: atoi函数的初步实现到完美优化

一. atoi函数简介


aoti把字符串转化成整型的一个函数


先看怎么使用

52f7d824da694b7ba146cfc48e05c124.png



传入一个字符类型的指针 变成一个整型的数据


话不多说 咱直接上代码


int main()
{
  char arr[20] = "1234";
  int a = atoi(arr);
  printf("%d", a);
  return 0;
}


代码演示的效果如下

0a100066c7d2487e8b4f479e4d6dc1dc.png

二. 简单实现


现在同学们大概了解了atoi这个函数怎么使用了吧


我们先来看看大概怎么实现这个函数

cf350c82946945398589484ecad5274a.png


我们大概用代码来实现一下


int my_atoi(char* str)
{
  int n = 0;
  while (*str)
  {
    n = n * 10 + (*str - '0');
    str++;
  }
  return n;
}


我们来看看效果


34c0a36abe164bce9de285ef966df8eb.png


能跑


但是! 如果你再面试的时候 回答这个实现方式的话 你很可能就要接受面试官的
压力测试了!


三. 面试官的压力测试


面试官: 我觉得你刚刚这个实现想法很好 但是你有没有考虑过这样子的情

况呢?


如果传入的是空指针怎么办呢?


如果传入的是空字符串怎么办呢?


如果传入的是非数字字符怎么办呢?


如果前面有空白字符怎么办呢?


如果前面有正负号怎么办呢?


除了我上面的说的那些问题是否还存在其他的问题呢?


这些你刚刚写的函数可以解决吗?


我: 鹅 我知道你很急 但是你先听我说


你先别急


我们这样来优化


四. 完美优化


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;
}


c0a3777cead04b82b97f8c70301d6c4d.png

01c44a0c05884ab8888ba774e5a1b462.png


以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏


希望大佬们看到错误之后能够不吝赐教 在评论区或者私信指正 博主一定及时修正


那么大家下期再见咯



相关文章
|
1月前
|
C语言
[字符串和内存函数]strcmp和strncmp以及memcmp的区别
[字符串和内存函数]strcmp和strncmp以及memcmp的区别
33 0
|
1月前
|
存储 安全 编译器
C/C中sizeof和strlen函数的实现:详细解析sizeof和strlen函数的实现机制、参数说明和使用技巧
C/C中sizeof和strlen函数的实现:详细解析sizeof和strlen函数的实现机制、参数说明和使用技巧
19 1
|
3月前
atoi()详解及其模拟实现
atoi()详解及其模拟实现
|
4月前
atoi函数的模拟实现
atoi函数的模拟实现
|
8月前
模拟实现atoi函数
模拟实现atoi函数
|
8月前
|
C语言
【C语言进阶】-- 重点字符串函数内存函数及其模拟实现(strlen,strcmp,strcat...memcpy,memmove)
【C语言进阶】-- 重点字符串函数内存函数及其模拟实现(strlen,strcmp,strcat...memcpy,memmove)
|
9月前
模拟实现atoi
模拟实现atoi
30 0
|
9月前
strstr(str1,str2) 函数与sscanf()函数功能详解
strstr(str1,str2) 函数与sscanf()函数功能详解
strcmp函数详解
如果字符串不一样,并且字符串1>字符串2,则返回值>0.相反返回值小于零。
248 0
<<C>>模拟atoi函数
<<C>>模拟atoi函数
61 0