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查询优化的技术从大方向上可以分为 物理查询优化,逻辑查询优化 物理查询优化:即通过建立索…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...