C语言 atoi 函数解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 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函数的学习,我相信你也会感觉到这个函数有好处也有缺陷,不过得用且用吧,在用的时候一定要脑子清醒,不要到头来骂这个函数,哈哈哈哈。


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

相关文章
|
2天前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
25 15
|
2天前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
38 24
|
2天前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
38 23
|
1天前
|
存储 编译器 C语言
【C语言程序设计——函数】回文数判定(头歌实践教学平台习题)【合集】
算术运算于 C 语言仿若精密 “齿轮组”,驱动着数值处理流程。编写函数求区间[100,500]中所有的回文数,要求每行打印10个数。根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码。如果操作数是浮点数,在 C 语言中是不允许直接进行。的结果是 -1,因为 -7 除以 3 商为 -2,余数为 -1;注意:每一个数据输出格式为 printf("%4d", i);的结果是 1,因为 7 除以 -3 商为 -2,余数为 1。取余运算要求两个操作数必须是整数类型,包括。开始你的任务吧,祝你成功!
15 1
|
1月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
153 14
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
75 10
|
1月前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
58 9
|
1月前
|
存储 Unix Serverless
【C语言】常用函数汇总表
本文总结了C语言中常用的函数,涵盖输入/输出、字符串操作、内存管理、数学运算、时间处理、文件操作及布尔类型等多个方面。每类函数均以表格形式列出其功能和使用示例,便于快速查阅和学习。通过综合示例代码,展示了这些函数的实际应用,帮助读者更好地理解和掌握C语言的基本功能和标准库函数的使用方法。感谢阅读,希望对你有所帮助!
45 8
|
1月前
|
C语言 开发者
【C语言】数学函数详解
在C语言中,数学函数是由标准库 `math.h` 提供的。使用这些函数时,需要包含 `#include <math.h>` 头文件。以下是一些常用的数学函数的详细讲解,包括函数原型、参数说明、返回值说明以及示例代码和表格汇总。
55 6
|
1月前
|
存储 C语言
【C语言】输入/输出函数详解
在C语言中,输入/输出操作是通过标准库函数来实现的。这些函数分为两类:标准输入输出函数和文件输入输出函数。
315 6

推荐镜像

更多