首页 > 其他分享 >atoi的模拟实现

atoi的模拟实现

时间:2023-03-18 22:31:58浏览次数:31  
标签:字符 compute 数字 实现 ret atoi 模拟 函数

文章主要介绍atoi的模拟实现,包含具体实现思路以及代码讲解;同时,对MSDN中atoi的作用进行了仔细介绍。 注:第一部分是在MSDN中的注解,第二部分包含笔者对函数的分析以及具体实现,第三部分则是笔者对于此模拟实现的一些缺陷说明。

一、atoi在MSDN中的注解

image.pngatoi函数将字符串转换为整型;

1、返回值

image.png当字符串可以转换为整型时,函数会返回一个整型的值(对于atoi); 不可以转换时,会返回0; 若产生溢出,返回值未定义,也就是说:数据溢出的话,atoi的处理会出错;

2、参数

image.png需要转换的字符串;

3、标注

image.png函数会将字符串转换为特定类型的数据,然后返回;在第一个字符未识别到数字时,函数会停止识别;用来识别的字符串可以是用于终止字符串的空字符\0;

二、具体实现

1、原函数测试

分析:

通过在MSDN中函数的描述,我们对atoi已经有了大概想法:

  • 函数将字符串转换为整型数据,然后返回;
  • 在识别第一个字符时,若遇到非数字,则会停止转换数据;
  • 转换成功时,返回转换值,失败则返回0;
  • 对于数据溢出的情况,atoi没有明确规定;
思考:

做了上述分析,但有些情况我们并不清楚,比如说:

  • 函数遇到空指针;
  • 函数第一个字符为+号或-号;
  • 函数遇到空白;
  • 字符串中同时存在数字与非数字的识别情况;
测试
  • 首先,遇到空指针时: image.png函数报错,故我们应限制,不可输入NULL;  

  • 遇到+号或-号时: image.png-号会返回负值; image.png+号返回正值; 也就是说,atoi函数的识别会包括 + - 符号;  

  • 遇到空白时: image.png函数会跳过空白字符,而在空白字符后的第一个字符开始转换;

  • 字符串同时存在数字与非数字: 非数字位于数字中: image.png函数在遇到非数字时停止转换; 数字位于非数字中:image.png函数未进行转换,便返回0; 数字中包含\0时: image.png由此可知:‘\0’也仅作为非数字字符串的一种,与非数字的处理相同;

2、实现

根据上述分析,已经清楚: atoi函数具有以下特点

  • 遇到非数字字符,停止识别,遇到数字字符,逐个识别为整型值; 定义内置compute函数,每识别一个字符,加到个位,同时原数据×10;
int compute(const char* s)
{
	int ret = 0;
	while (isdigit(*s))
	{
		ret = ret * 10 + (*s++ - '0');
	}
	return ret;
}
  • 遇到空白会跳过; 由于空白的字符表示是‘\t’,因此只需循环跳过字符串开始的空白即可;
while ((*s++) == '\t');
  • 只在除去空白后的第一个位置识别正负符号; 正负号的判断在第一个位置执行,因此只需一次if语句,判断即可;
	if (isdigit(*s))
	{
		ret = compute(s);
	}
	else if (*s == '-')
	{
		ret = -compute(s + 1);
	}
	else if (*s == '+')
	{
		ret = compute(s + 1);
	}
	else
	{
		return 0;
	}
  • 存在边界问题,数据溢出返回值无法预测; 此处笔者暂时未想到合适的方法判断数据溢出,在上述的实现中,若存在数据溢出,则返回值不可靠;  

三、模拟实现

总代码:

由具体分析实现代码如下:

//计算转换字符值
int compute(const char* s)
{
	int ret = 0;
	while (isdigit(*s))
	{
		ret = ret * 10 + (*s++ - '0');
	}
	return ret;
}
int my_atoi(const char* s)
{
	//判空
	assert(s);
	int ret = 0;
	//跳过空白
	while ((*s++) == '\t');
	//判别第一个字符
	if (isdigit(*s) || *s == '+')
	{
		ret = compute(s);
	}
	else if (*s == '-')
	{
		ret = -compute(s + 1);
	}
	else
	{
		return 0;
	}
	return ret;
}

缺陷:

  • 无法判断数据是否溢出; 当数据超过int可表示的最大值时(也就是除符号位外全为1): image.png 则会将后续的1顶到符号位上,从而造成数据的不准确。

标签:字符,compute,数字,实现,ret,atoi,模拟,函数
From: https://blog.51cto.com/u_15423682/6129837

相关文章

  • 使用matlab机器视觉工具箱实现人脸特征的检测和定位,识别并标注眉毛,眼睛,鼻子,嘴巴
    1.算法描述       机器视觉工具箱(MVTB)提供了许多在机器视觉和基于视觉的控制中有用的功能。这是一个有点折衷的收藏品,反映了作者对光度学、摄影测量学、色度学等......
  • commitlint 结合 husky 实现提交信息格式校验(2023-03-18)
    为什么要对git提交信息进行格式校验通过对提交信息进行格式校验能统一规范,这在团队协作过程中显得格为重要。符合规范的提交信息能很好反映此次提交的的目的,内容和......
  • 光场原理及一些算法代码实现
    2023.3.18好久没有写过博客了,感觉自己比以前更菜了\(//∇//)\好不容易的更新,是为了把最近看的几篇光场论文写个自己的整理和理解,后面可能会写一些用C++实现的光场处理算......
  • FIRE的实现理论
     FIRE的实现理论在《我这样的男人》中提到,如果以手中积蓄作首付在大城市置业,就得再兢兢业业干上30年。 反过来想,如果放弃该计划,是不是就可以不再逆来顺受、忧虑失业......
  • 在IDEA中使用JRebel插件实现热部署(包括mybatis的xml文件)
    省流版下载插件JRebelandXRebel和JRebelmybatisPlusextension详细版首先,我的IDEA下载了官方中文插件(Chinese​(Simplified)​LanguagePack/中文语言包),所以在......
  • 3.5 链栈的表示和实现
    链栈的表示链栈是运算受限的单链表,只能在链表头部进行操作typedefstructStackNode{ SElemTypedata;StructStackNode*next;}StackNode,*LinkStack;LinkSta......
  • 3.7 队列的表示和实现
    3.5队列的表示和操作实现相关术语队列(Queue)是仅在表尾进行插入操作,在表头进行删除操作的线性表。表尾及a(((((n)))))端,称为队尾;表头即a(((((1)))))端称为......
  • 3.8 队列的顺序表示和实现
    3.5.2队列的顺序表示和实现队列的物理存储可以用顺序结构,也可用链式存储结构,相应地队列的存储方式也分为两种,即顺序队列和链式队列、队列的顺序表示——————......
  • 3.9 队列的链式表示和实现
    3.5.3队列的链式表示和实现适用于用户无法估计所用队列的长度,则适宜采用该类型的队列链式队列的结构图如下所示链队列的类型定义//这里是定义是每个节点类型t......
  • 3.3 栈的表示和实现
    1、栈的抽象数据类型定义ADTStack{ 数据对象: D={ai|ai∈ElemSet,i=1,2,3,...,n。n>=0} 数据关系: R1={<ai-ai>|ai-1andai∈D,i=2,...,n} 约定an端为栈顶,a......