C语言模拟实现:atoi函数
在实现atoi之前我们先来了解一下atoi函数的作用是什么:
目录
1.实例演示
2.模拟实现
2.1 判断是否为空指针
2.2判断是否为空字符串
2.3判断正负号
2.4判断非数字字符
2.5判断是否越界
2.6完整代码
1.实例演示
//实例演示
#include <stdio.h>
#include <stdlib.h>
int main()
{printf("%d\n", atoi("0"));printf("%d\n", atoi("1234"));printf("%d\n", atoi("-1234"));printf("%d\n", atoi("+1234"));printf("%d\n", atoi("12a4"));return 0;
}

2.模拟实现
如果单从对atoi函数的解释上来看,就是将字符串转化为整数,如果只是简单的按照将字符串转化为整数的思路来模拟实现atoi函数,也可以,但是远远不够,但是还是给大家来演示一下:
要想将字符数字转化为整数数字,之前提到过:数字1加上字符0就转化为了字符1
(1 + '0' = '1') ,给字符1减去字符0就得到了数字1('1' - '0' = 1),所以在模拟实现atoi的时候就可以使用这样的方法,使用指针来遍历字符串,给第一个字符减字符0得到该数字,然后地址加一转化第二个字符,直到遇到'\0'.
//模拟实现
#include <stdio.h>
int my_atoi(const char* str)
{int ret = 0;while (*str){//将转化后的值赋值给retret = ret * 10 + (*str - '0');//ret = 0 * (10 + '1') - '0'//ret = 1 * (10 + '2') - '0'//ret = 12 * (10 + '3') - '0'//ret = 123 * (10 + '4') - '0'//ret = 1234//转化成功之后地址加1str++;}return ret;
}
int main()
{char str[] = {"1234"};int ret = my_atoi(str);printf("%d\n", ret);return 0;
}
虽然这样实现可以将字符串转化为整数,但是还是存在许许多多的问题:
1. 如果传递的是空指针
2. 如果传递的是空字符串
3. 如果传递的是带'+'、'-'的字符串
4. 如果传递的是非数字字符
5. 转化之后的值越界
所以以上的问题都是在写代码的时候要考虑的,那么接下来我们来一一的解决:
2.1 判断是否为空指针
判断一个指针是否为空指针,用到assert这个宏来断言,但是在使用这个宏时需要包含头文件<assert.h>
#include <assert.h>
int my_atoi(const char* str)
{//1.//判断是否为空指针//assert来断言assert(str);
}
2.2判断是否为空字符串
若为空字符串,那么它的整个字符串都是'\0',所以要通过指针来判断它是否为'\0',如果为'\0',那么就要返回0,但是存在一个问题,如果传给atoi的就是字符0呢?,那也返回的是0,那到底返回的0是合法转化还是非法转化的呢?因此我们需要进行判断。在这里可以使用枚举,将非法和合法都列举出来,然后先将其设置为非法,如果是合法的转化,在后面的设置中将其转化为合法就可以了。
enum State
{VALID, //合法INVALID //非法
};
//先将State设置为非法enum State date = INVALID;
int my_atoi(const char* str)
{//1.//判断是否为空指针//assert来断言assert(str);//2.//判断是否为空字符串if (*str == '\0'){return 0; //这里返回的时候,date还是非法,所以表示非法转化}
}
2.3判断正负号
判断正负这一步需要在转化字符为数字的时候将正负号添加进去,因此我们可以设置一个标记正负号的值,如果为正号就不变,若为负号就变为负数
#include <stdio.h>
#include <assert.h>
enum State
{VALID, //合法INVALID //非法
};
//先将State设置为非法enum State date = INVALID;
int my_atoi(const char* str)
{//1.//判断是否为空指针//assert来断言assert(str);//2.//判断是否为空字符串if (*str == '\0'){return 0; //这里返回的时候,date还是非法,所以表示非法转化}//3.//判断正负int flag = 0;if (*str == '+'){flag = 1;str++;}else if (*str == '-'){flag = -1;str++;}
}
2.4判断非数字字符
在之前的字符分类函数中提到过判断数字字符,其中有一个函数是isdigit,它是用来判断10进制的数字,它在使用的时候需要包含头文件<ctype.h>
//4.//判断是否为非数字字符long long ret = 0; //设置一个值来进行存放转化之后的值//这里使用long long类型的ret是为了在转化的时候防止转换之后的值溢出while (*str){if (isdigit(*str)) //isdigit函数是用来判断是否为10进制的数字{ret = ret * 10 + flag * (*str - '0'); //如果为10进制数字就正常转化//将flag也引入来表示正、负数}else //如果不为10进制的数字就将之前转化的返回{return (int)ret; //因为ret是long long类型,而atoi的返回类型是int所以要强制类型转化}str++;}
2.5判断是否越界
整形的最大值是一个INT_MAX的值,最小值是一个INT_MIN的值,所以我们需要将转化之后的值进行判断,如果转换之后在这个范围内,那表示正常转化,如果超出了这个范围,则表示非法转化,在使用时需要包含头文件<limits.h>
//4.//判断是否为非数字字符long long ret = 0; //设置一个值来进行存放转化之后的值//这里使用long long类型的ret是为了在转化的时候防止转换之后的值溢出while (*str){if (isdigit(*str)) //isdigit函数是用来判断是否为10进制的数字{ret = ret * 10 + flag * (*str - '0'); //如果为10进制数字就正常转化//将flag也引入来表示正、负数//5.//判断是否越界if (ret > INT_MAX || ret < INT_MIN){return (int)ret;}}else //如果不为10进制的数字就将之前转化的返回{return (int)ret; //因为ret是long long类型,而atoi的返回类型是int所以要强制类型转化}str++;}//正常遍历完字符串之后if (*str == '\0'){//当正常转化完之后,将date赋值为合法date = VALID;}return (int)ret;
2.6完整代码
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <limits.h>enum State
{VALID, //合法INVALID //非法
};
//先将State设置为非法
enum State date = INVALID;
int my_atoi(const char* str)
{//1.//判断是否为空指针//assert来断言assert(str);//2.//判断是否为空字符串if (*str == '\0'){return 0; //这里返回的时候,date还是非法,所以表示非法转化}//3.//判断正负int flag = 0;if (*str == '+'){flag = 1;str++;}else if (*str == '-'){flag = -1;str++;}//4.//判断是否为非数字字符long long ret = 0; //设置一个值来进行存放转化之后的值//这里使用long long类型的ret是为了在转化的时候防止转换之后的值溢出while (*str){if (isdigit(*str)) //isdigit函数是用来判断是否为10进制的数字{ret = ret * 10 + flag * (*str - '0'); //如果为10进制数字就正常转化//将flag也引入来表示正、负数//5.//判断是否越界if (ret > INT_MAX || ret < INT_MIN){return (int)ret;}}else //如果不为10进制的数字就将之前转化的返回{return (int)ret; //因为ret是long long类型,而atoi的返回类型是int所以要强制类型转化}str++;}//正常遍历完字符串之后if (*str == '\0'){//当正常转化完之后,将date赋值为合法date = VALID;}return (int)ret;}
int main()
{char str[] = { "-123456" };printf("转化前:> %s\n", str);int ret = my_atoi(str);if (date == INVALID){printf("非法转化:> %d\n", ret);}elseprintf("合法转化:> %d\n", ret);return 0;
}
总结:
1. 模拟实现atoi函数时不能只简单的去将数字字符转化为整数,还得考虑其它因素(空指针、空字符串、正负数、是否为数字字符、越界)。
2. 使用各种辅助函数时对应头文件的包含。
3. 熟悉字符分类函数。
4. 字符数字如何转化为整数数字
关于atoi函数的模拟实现就写到这里,如果大家喜欢,请留下你的三连,抱拳感谢了!!
相关文章:
C语言模拟实现:atoi函数
在实现atoi之前我们先来了解一下atoi函数的作用是什么: 目录 1.实例演示 2.模拟实现 2.1 判断是否为空指针 2.2判断是否为空字符串 2.3判断正负号 2.4判断非数字字符 2.5判断是否越界 2.6完整代码 1.实例演示 //实例演示 #include <stdio.h> #include …...
LeetCode.每日一题 2427. 公因子的数目
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
蓝牙BQB认证 - HFP profile配置说明
零.声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。 第二篇:Trans…...
【接口测试工具】Eolink Apikit 快速入门教程
Eolink Apikit 下载安装【官方版】:https://www.eolink.com/apikit 发起 API 测试 进入 API 文档详情页,点击上方 测试 标签,进入 API 测试页,系统会根据 API 文档自动生成测试界面并且填充测试数据。 填写请求参数 首先填写好请…...
使用Python和OpenCV实现实时人脸检测并保存截图
在本篇博客中,我们将使用Python和OpenCV库实现一个实时人脸检测的小项目。我们将利用OpenCV中的Haar级联分类器来检测摄像头捕获的图像中的人脸。 项目功能 通过摄像头实时捕获视频流。使用Haar级联分类器检测视频帧中的人脸。在检测到的人脸周围绘制矩形框。实时…...
[linux kernel]slub内存管理分析(7) MEMCG的影响与绕过
文章目录背景前情回顾描述方法约定MEMCG总览省流总结简介slub 相关 memcg机制kernel 5.9 版本之前结构体初始化具体实现kernel 5.9-5.14kernel 5.14 之后突破slab限制方法cross cache attackpage 堆风水总结背景 前情回顾 关于slab几个结构体的关系和初始化和内存分配和释放的…...
MySQL创建数据库(CREATE DATABASE语句)
在 MySQL 中,可以使用 CREATE DATABASE 语句创建数据库,语法格式如下: CREATE DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>] [[DEFAULT] COLLATE <校对规则名>]; [ ]中的内容是可选的。语…...
【JavaWeb】4—Tomcat
⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 如果文章对你有所帮助,可以点赞👍…...
宝塔Linux面板部署Python flask项目
目录 👉1、前言 👉2、安装python项目管理器 👉3、上传项目文件及文件夹 👉4、配置项目 👉5、请求测试 学习记录: 👉1、前言 写在前面:前几天我们实现了外网内外登录正方教务系…...
spring中产生bean的几种方式
BeanImportMyImportSelector implements ImportSelectorMyImportBeanDefinitionRegistarimplements ImportBeanDefinitionRegistrarFactoryBean这里着重讲解FactoryBean如何判断当前bean是否是FactoryBeanorg.springframework.beans.factory.support.AbstractBeanFactory#isFac…...
OD-火星文计算(Python)
火星文计算 题目描述 已经火星人使用的运算符号为# $ 其与地球人的等价公式如下x#y2*x3*y4x$y3*xy2x y是无符号整数 地球人公式按照c语言规则进行计算 火星人公式中$符优先级高于#相同的运算符按从左到右的顺序运算 输入描述 火星人字符串表达式结尾不带回车换行 输入的字符…...
【vue3教程】初入了解vue3的基本结构
前言 Animatrix:黑客帝国 Blade Runner:银翼杀手 Cowboy Bebop:星际牛仔 Dragon Ball:龙珠 Evangelion:新世纪福音战士 Ghostin the Shell:攻壳机动队 Hunter X Hunter:全职猎人 Initial D&…...
智慧供水综合运营平台解决方案
一、概述 建设背景: 供水系统是城市生存、发展的基础,供水事业的发展与城市的社会经济发展息息相关,其服务质量的好坏不仅关系到供水企业自身的利益,也直接影响到社会的稳定和政府形象。住房城乡建设部于2012年12月5日正式发布了《…...
文件系统、描述符和缓冲区
目录 🏆一、文件系统 1、open ①对open接口的介绍 ②接口使用 2、write接口 3、read接口 🏆二、深入理解文件描述符fd 1、fd具体实质 2、文件fd的分配规则 3、fd重定向 ①输出重定向 ②追加重定向 ③输入重定向 ④文件的引用计数 🏆三…...
java微服务商城高并发秒杀项目--009.流控规则和降级规则
线程流控(只要线程数达到了指定数量,访问就会被流控):warm up流控效果(慢慢增加QPS的数量,之后最后达到阈值,这种情况下,一开始会容易限流,后期就不会限流了)…...
php编写的脚本,如何才能在windows系统运行呢?
咱们要在Windows系统上运行PHP脚本,需要安装PHP解释器和Web服务器。 以下是基本的步骤,很简单: 下载PHP解释器:可以从官方网站 https://windows.php.net/download/ 下载Windows版本的PHP解释器。根据你的操作系统和需要的版本选…...
政务综合服务平台建设项目方案书
本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除 目 录 第一章 项目整体概述 1.1. 项目名称 1.2. 建设单位 1.3. 编写依据 1.3.1 相关政策 1.3.2 技术标准 1.4. 建设目标、规模、内容、建设期 1.4.1 建设目标 1.4.2 …...
python好玩的短代码
Python语言是一种流行的编程语言,在 Python语言中有很多有趣的特性,比如: 1.变量可以定义为字符串,也可以定义为字符串对象 2.变量可以用来初始化一个函数或模块,函数或者模块可以定义成一个类,这个类被称为…...
会Python如何学习C#的几个关键点
Python和C#都是常用的编程语言,但两者之间存在一些重要的区别。如果你已经掌握了Python并希望学习C#,以下是几个关键点: 面向对象编程(OOP):C#是一种严格的面向对象编程语言,而Python则具有更灵…...
索引失效原则与查询优化
数据库调优的维度: 索引建立SQL优化(本文重点)my.cnf的调整(线程数,缓存等)分库分表 SQL查询优化的技术从大方向上可以分为 物理查询优化,逻辑查询优化 物理查询优化:即通过建立索…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...


