C语言 atoi 函数解析

简介: C语言 atoi 函数解析

前言


  • 对于atoi函数大家可能会有些陌生,不过当你选择并阅读到这里时,请往下阅读,我相信你能对atoi函数熟悉
  • 该函数的头文件为 <stdlib.h><cstdlib>


atoi函数的介绍

此函数的功能是将数字字符的字符串转化为字面上的整型返回,例如:


char arr[] = "1234";
将”1234“ -> 1234(int)


以下是函数原型:

a562eff462a3489c8985cbe66ef08a4e.png


01cd7036bd444e879c1466e5e43ac2ba.png

要注意的点:


如果字符串从开头就有连续的空格字符,则跳过这些连续的空格字符,找到不是空格的字符。

如果跳过这些空格字符后的第一个字符不是数字字符,则直接返回0;

如果跳过这些空格字符后的第一个字符是数字字符,则从这个数字字符开始转换,并向后找连续的数字字符转换 ,如果连续中断,找到不是数字字符的字符,则在此截断寻找,返回前面已经转换好的连续的数字字符字面整型值。(这里截断向后寻找后,不管后面有没有数字字符函数都不管)


509a18cf99a142018a1aa56fb2e10ec3.png


  • 如果字符串首元素不是空格字符
  1. 如果第一个字符不是数字字符,直接返回0
  2. 如果第一个字符是数字字符, 则从这个数字字符开始转换,并向后找连续的数字字符转换 ,如果连续中断,找到不是数字字符的字符,则在此截断寻找,返回前面已经转换好的连续的数字字符字面整型值。



5efaf065ec0e46aabe153cd90a44d9dd.png


  • 如果字符串全部为空格字符,返回0;如果为空字符串,返回0;

atoi函数的使用


  • 有了上面的介绍,使用的意图变得明显,使用起来也就随手就来了。

例如:

#include <stdio.h>
#include <stdlib.h>
int main()
{
  char a[] = "";
  char b[] = "     ";
  char c[] = "66666";
  char d[] = "    @. 66ab";
  char e[] = "    6666@qq.com";
  char f[] = "520hehe";
  char g[] = "i love you 555";
  printf("%d\n", atoi(a));
  printf("%d\n", atoi(b));
  printf("%d\n", atoi(c));
  printf("%d\n", atoi(d));
  printf("%d\n", atoi(e));
  printf("%d\n", atoi(f));
  printf("%d\n", atoi(g));
  return 0;
}


b4630f7e77234d199eda5ea5b0153ae6.png


看上的结果,是不是就与介绍当中的点都对应起来了呢?


atoi函数的自我实现


有了上面的铺垫,我们已经了解了该函数的特性,所以接下来的实现也就变的简单了


  1. 跳过空格字符(也可能没有,就不跳直接开始判断转换);
  2. 跳过后开始判断转换;
  3. 无论何种方式开始判断第一个字符,如果不是数字字符,直接返回0。
#include <stdio.h>
#include <assert.h>
// 数字ASCLL码值范围为 48—57
int my_atoi(const char* str)
{
  assert(str);
  const char* tmp = str;
  while (*tmp == ' ')  // 跳过空格字符
    tmp++;
  int num = 0; // 转换数字字符值的接收变量
  // 如果是数字字符,就进来,到不连续处就停止
  while (*tmp <= 57 && *tmp >= 48)  
  {
    num = num * 10 + (*tmp - '0');
    if (*(tmp + 1) < 48 || *(tmp + 1) > 57)
    {
      return num;
    }
    tmp++;
  }
  // 如果开始判断的字符不是数字字符,前面的循环不进去,这里直接返回0
  return 0;
}
int main()
{
  char a[] = "";
  char b[] = "     ";
  char c[] = "66666";
  char d[] = "    @. 66ab";
  char e[] = "    6666@qq.com";
  char f[] = "520hehe";
  char g[] = "i love you 555";
  printf("%d\n", my_atoi(a)); // 0
  printf("%d\n", my_atoi(b)); // 0
  printf("%d\n", my_atoi(c)); // 66666
  printf("%d\n", my_atoi(d)); // 0
  printf("%d\n", my_atoi(e)); // 6666
  printf("%d\n", my_atoi(f)); // 520
  printf("%d\n", my_atoi(g)); // 0
  return 0;
}


附:C++完整无缺版自我实现


前面C语言实现的atoi函数不够严谨,这里用c++实现严谨的atoi函数


class Solution {
public:
    int myAtoi(string s) {
        int flag = 1; // 操作正负数
        reverse(s.begin(), s.end());  // 先逆置
        while (s.size() > 1 && s.back() == ' ') s.pop_back(); // 除去前导‘0’ ,如果全是‘0’保留一个‘0’返回
        if (s.back() == '-') flag = -flag, s.pop_back(); // 利用flag来控制正负情况
        else if (s.back() == '+') s.pop_back();
        if (s.back() < 48 || s.back() > 57) return 0;  // 前面的工作完成后开始判断第一个位置是不是数字字符
        long long ret = 0;  // 怕存爆整型
        while (s.size() > 0)
        {
          // 这一步如果存的时候就已经超过了int最大或小于最小,直接返回最大或最小
            if ((int)ret != ret) 
                if (ret * flag < 0) return INT_MIN;
                else return INT_MAX;
            if (s.back() >= 48 && s.back() <= 57)
            {
                // 每操作一次就删除那个数字字符
                ret = ret * 10 + (s.back() - '0');
                s.pop_back();
            }
            else
            {
              // 找到第一个不是数字字符就跳出
                break;
            }
        }
        ret *= flag;
        if ((int)ret != ret)
            if (ret < 0) return INT_MIN;
            else return INT_MAX;
        else return (int)ret;
    }
};


写在最后


相信你已经对这个函数了如指掌了,认识掌握的函数越多,当然是没有坏处只有好处的。经过对atoi函数的学习,我相信你也会感觉到这个函数有好处也有缺陷,不过得用且用吧,在用的时候一定要脑子清醒,不要到头来骂这个函数,哈哈哈哈。


感谢阅读本小白的博客,错误的地方请严厉指出噢!

相关文章
|
5月前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
1124 0
|
7月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
366 15
|
12月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
510 1
一文彻底搞清楚C语言的函数
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
703 16
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
589 3
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
474 2
|
存储 编译器 C语言
【C语言程序设计——函数】回文数判定(头歌实践教学平台习题)【合集】
算术运算于 C 语言仿若精密 “齿轮组”,驱动着数值处理流程。编写函数求区间[100,500]中所有的回文数,要求每行打印10个数。根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码。如果操作数是浮点数,在 C 语言中是不允许直接进行。的结果是 -1,因为 -7 除以 3 商为 -2,余数为 -1;注意:每一个数据输出格式为 printf("%4d", i);的结果是 1,因为 7 除以 -3 商为 -2,余数为 1。取余运算要求两个操作数必须是整数类型,包括。开始你的任务吧,祝你成功!
279 1
|
11月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1075 29
|
11月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
460 4
|
11月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
  • DNS