【C语言】模拟实现atoi函数
atoi(表示 ascii to integer)是把字符串转换成整型数的一个函数.
atoi()函数会扫描参数 nptr字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过isspace( )函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回0
我们在模拟实现atoi函数时,要注意以下几点:
1.字符串之前的空白问题
2.正负号
3.字符串为空时
4.被转换的数字过于大(正溢出、负溢出)
5.其他,无法转换的情况(全是字母....之类的)
我们了解atoi函数功能和一些注意事项之后,开始模拟实现它,代码如下:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
enum{
vaild = 0,
invaild = 1
};
int flag = vaild;
int my_atoi(const char *str){
long long ret = 0;
int symbol = 1;
//断言str!=NULL
assert(str);
//判断空字符
if( '\0' == *str ){
flag = invaild;
return 0;
}
//去掉空格、制表符
while(isspace(*str)){
str++;
}
//符号位判断
if('-'==*str){
symbol = -1;
str++;
}else if('+'==*str){
str++;
}else if(((*str<='0')&&(*str>='9'))){
flag = invaild;
return 0;
}
//其他异常情况处理完毕,开始转换
while((*str!='\0')&&(*str>='0')&&(*str<='9')){
ret = (ret*10 + *str-'0');
str++;
}
//带上符号位
ret *= symbol;
//检测溢出
//int 0111 1111 1111 1111 1111 1111 1111 1111 正溢出
// 7 f f f f f f f
// 1000 0000 0000 0000 0000 0000 0000 0000 负溢出
// 8 0 0 0 0 0 0 0
if(((ret>0x7fffffff)&&(1==symbol)) ||
(ret<(signed int)0x80000000)&&(-1==symbol)){
flag = invaild;
return 0;
}
//ret合法
flag = vaild;
return ret;
}
//打印atoi函数状态+\n
void PrintState(){
if(flag){
printf("异常\n");
}else{
printf("正常\n");
}
}
//测试函数
void FunTest(){
printf("value=%d,state=",my_atoi("123456789"));
PrintState();//正常
printf("value=%d,state=",my_atoi("-123456789"));
PrintState();//正常
printf("value=%d,state=",my_atoi("-123456789sassa"));
PrintState();//正常,遇到字母终止
printf("value=%d,state=",my_atoi(" -123456789sassa"));
PrintState();//正常,前面带空格
printf("value=%d,state=",my_atoi(""));
//////////////异常情况/////////
printf("\n\n");
PrintState();//异常:空字符串
printf("value=%d,state=",my_atoi("123456789123456789"),flag);
PrintState();//异常:正溢出
printf("value=%d,state=",my_atoi("-123456789123456789"),flag);
PrintState();//异常:负溢出
printf("value=%d,state=",my_atoi("dasdsa"),flag);
PrintState();//异常:无法转换
}
int main(){
FunTest();
return 0;
}
彩蛋:在写测试函数时,有一件事,始终不得其解,一开始我将测试代码写成了这样:
void FunTest(){
printf("value=%d,state=%d\n",my_atoi("123456789"),flag);//正常
printf("value=%d,state=%d\n",my_atoi("-123456789"),flag);//正常
printf("value=%d,state=%d\n",my_atoi("-123456789sassa"),flag);//正常,遇到字母终止
printf("value=%d,state=%d\n",my_atoi(" -123456789sassa"),flag);//正常,前面带空格
printf("\n\n\n");
printf("value=%d,state=%d\n",my_atoi(""),flag);//异常:空字符串
printf("value=%d,state=%d\n",my_atoi("123456789123456789"),flag);//异常:正溢出
printf("value=%d,state=%d\n",my_atoi("-123456789123456789"),flag);//异常:负溢出
printf("value=%d,state=%d\n",my_atoi("dasdsa"),flag);//异常:无法转换
}
测试时,发现一件诡异的事情!!!!!!!
结果输出是这样:
value=123456789,state=0
value=-123456789,state=0
value=-123456789,state=0
value=-123456789,state=0 value=0,state=0 //卧槽!!!为什么是0?
value=0,state=1
value=0,state=1
value=0,state=1
我还特意跟进函数体内看,发现全局变量flag确实被改为了1,但为什么输出的是0呢???
正当我百思不得其解时,突然想到printf函数的调用约定是_cdel!!!!
因此,_cdel调用约定,是将参数由右向左压栈,因此它先将flag压栈,然后再执行my_atoi函数,在my_atoi函数体内修改了全局变量flag.....
所以,最终输出了0!
因此,才有了最终代码!
【C语言】模拟实现atoi函数的更多相关文章
- C语言::模拟实现strlen函数
题目要求 编写一个C语言程序模拟实现strlen函数. 算法 strlen函数功能是计算字符串中字符的个数.(除\0外) 而字符串本身就是一个字符数组,只不过末尾以\0结束. 因此,我们只需遍历除\0 ...
- 【c语言】 模拟实现库函数的atoi函数
// 模拟实现库函数的atoi函数 #include <stdio.h> #include <string.h> #include <assert.h> #incl ...
- C语言itoa()函数和atoi()函数详解(整数转字符C实现)
1.int/float to string/array: C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明. ● itoa():将 ...
- C语言itoa()函数和atoi()函数详解(整数转字符)
http://c.biancheng.net/cpp/html/792.html C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. 以下是用itoa()函数将整 ...
- C语言itoa函数和atoi 函数
C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串.以下是用itoa()函数将整数转 换为字符串的一个例子: # include <stdio.h> ...
- [置顶]
C语言itoa()函数和atoi()函数详解(整数转字符C实现)
头文件:#include <stdlib.h> atoi() 函数用来将字符串转换成整数(int),其原型为: int atoi (const char * str); [函数说明]ato ...
- 【转载】C语言itoa()函数和atoi()函数详解(整数转字符C实现)
本文转自: C语言itoa()函数和atoi()函数详解(整数转字符C实现) 介绍 C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. int/float to ...
- C语言itoa()函数和atoi()函数详解(整数转字符C实现)【转载】
文章转载自https://www.cnblogs.com/bluestorm/p/3168719.html C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. ...
- C语言atoi函数
目录 1.包含头文件 2.函数声明 3.功能说明 4.示例 5.其它说明 6.版权声明 C语言提供了一系列函数把字符串转换为整数:atoi.atol.atoll和atoq. 1.包含头文件 #incl ...
随机推荐
- django源码简析——后台程序入口
这一年一直在用云笔记,平时记录一些tips或者问题很方便,所以也就不再用博客进行记录,还是想把最近学习到的一些东西和大家作以分享,也能够对自己做一个总结.工作中主要基于django框架,进行项目的开发 ...
- Oracle索引语句整理
转载:http://www.cnblogs.com/djcsch2001/articles/1823459.html 索引,索引的建立.修改.删除 索引索引是关系数据库中用于存放每一条记录的一种对象, ...
- MASM32使用教程
代码如果你在用汇编语言来开发windows下的程序的话,MASM32是很好的选择. (Masm32下载地址请用google搜索罢.) 工欲善其事,必先利其器. 本文主要针对masm32 v8来说明三点 ...
- Android开发8:数据存储(二)——SQLite数据库和ContentProvider的使用
前言 啦啦啦各位小伙伴们许久不见了~学期末和过年期间自己忙着做其他事没能及时更新Android开发系列课程的博客,实在是罪过罪过~ 好啦~废话不多说,进入我们今天的主题.今天我们将和大家学习其他的数据 ...
- 前端总结·基础篇·CSS(二)视觉
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·CSS(四)兼容 目录 一.动画(animation)(IE ...
- JavaScript内置对象-Array
▓▓▓▓▓▓ 大致介绍 除了Object之外,Array类型恐怕就是JavaScript种最常用的类型了,JavaScript中的数组与其他语言中的数组有很大的区别,例如,数组的每一项可以存放任何值, ...
- iOS开发学习路径的一些建议
结合自己情况聊下iOS学习建议,这里不讲大道理,说说具体怎么做.欢迎大家拍砖. 1.第一点要求 ,能比较顺畅的阅读官方的文档 如果你连官方的文档读起来都非常困难,那你还谈什么提高和进阶,咱们学习iOS ...
- Unity Shader 知识点总结(一)
在学习了一段时间的Unity Shader后,打算写一些知识总结,便于今后的查找.如有错误,希望大家指出更改. 本文参照的unity入门精要一书,做一个知识归纳,如有兴趣可以看看其开源的部分,是一本比 ...
- 定制Maven的ArcheType
根据需要定制Maven的ArcheType的好处不言而喻了,我就不再啰嗦.定制一般通过从Maven的项目构建,比手动构建省去了配置文件的编写.资源文件的复制等繁琐的操作,下面我们就说下从Maven项目 ...
- Oracle-操作
登录PL_SQL,输入用户名sys 密码 安装时输入的密码,选择 sysdba 打开plsqldev.exe所在目录下的PlugIns文件夹,如果没有请从其它地方拷入 打开运行命令窗口,输入命令 re ...