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函数的更多相关文章

  1. C语言::模拟实现strlen函数

    题目要求 编写一个C语言程序模拟实现strlen函数. 算法 strlen函数功能是计算字符串中字符的个数.(除\0外) 而字符串本身就是一个字符数组,只不过末尾以\0结束. 因此,我们只需遍历除\0 ...

  2. 【c语言】 模拟实现库函数的atoi函数

    // 模拟实现库函数的atoi函数 #include <stdio.h> #include <string.h> #include <assert.h> #incl ...

  3. C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    1.int/float to string/array: C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明. ● itoa():将 ...

  4. C语言itoa()函数和atoi()函数详解(整数转字符)

    http://c.biancheng.net/cpp/html/792.html C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. 以下是用itoa()函数将整 ...

  5. C语言itoa函数和atoi 函数

    C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串.以下是用itoa()函数将整数转 换为字符串的一个例子: # include <stdio.h>  ...

  6. [置顶] C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    头文件:#include <stdlib.h> atoi() 函数用来将字符串转换成整数(int),其原型为: int atoi (const char * str); [函数说明]ato ...

  7. 【转载】C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    本文转自: C语言itoa()函数和atoi()函数详解(整数转字符C实现) 介绍 C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. int/float to ...

  8. C语言itoa()函数和atoi()函数详解(整数转字符C实现)【转载】

    文章转载自https://www.cnblogs.com/bluestorm/p/3168719.html   C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. ...

  9. C语言atoi函数

    目录 1.包含头文件 2.函数声明 3.功能说明 4.示例 5.其它说明 6.版权声明 C语言提供了一系列函数把字符串转换为整数:atoi.atol.atoll和atoq. 1.包含头文件 #incl ...

随机推荐

  1. JavaScript中国象棋程序(5) - Alpha-Beta搜索

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第5节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  2. 在内存充足时malloc函数分配内存失败的原因及解决

    昨天在修改自己的代码的时候,碰到了malloc函数内存分配失败,上网翻了翻,一个很可能的原因是之前的代码出现了越界操作,导致malloc分配函数所涉及的一些信息被破坏.在这个思想的指导下,今天又是郁闷 ...

  3. 关于H5里的API,上传图片预览功能

    FileReader:读取本地图片文件并显示 写在开头 之前公司要求做一个H5页面,功能是照相和选择相册相片,并且能在屏幕上预览.然后我就傻里吧唧的各种找插件,因为有些插件不适配手机的型号,安卓机基本 ...

  4. tornado学习 - TCPClient 实现聊天功能

    之前完成了一个简单的聊天服务器,连接服务器使用的是系统自带nc命令,接下来就是通过自己实现TCPClient. 客户端与服务器功能大致相仿,相对与服务器只是少了转发消息环节. 首先,定义TCPClie ...

  5. GitHub客户端Desktop的安装和使用总结

    前言 这段时间想把我写的东西上传到GitHub上,所以开始收集资料学习,走了很多弯路( msysgit和极慢的FQ网速让我欲仙欲死),最后找到了比较好用的工具GitHub Desktop.在此做出自己 ...

  6. 淘宝API调用 申请 获取session key

    在调用淘宝的API时,我们都会用到appkey,appsecret,appsession. 1.我们申请应用就会有appkey和appsecret了 2.正式环境下获取SessionKey 注意:we ...

  7. Node.js~在linux上的部署

    我们以centOS为例来说说如何部署node.js环境 一 打开centos,然后开始下载node.js包 curl --silent --location https://rpm.nodesourc ...

  8. 【转载】JavaScript继承详解(二)

    这一章我们将会重点介绍JavaScript中几个重要的属性(this.constructor.prototype), 这些属性对于我们理解如何实现JavaScript中的类和继承起着至关重要的作用. ...

  9. java里Struts2学习登录练习详解

    最近在学struts2里面遇到很多错误,今天跟大家分享一下,我的开发工具是Eclipse: 1.到网上下载Struts2的包,这里不再累赘,百度有很多: 2.新建一个项目,记得后面加上web.xml文 ...

  10. 《深入理解Java虚拟机》学习笔记之类加载

    之前在学习ASM时做了一篇笔记<Java字节码操纵框架ASM小试>,笔记里对类文件结构做了简介,这里我们来回顾一下. Class类文件结构 在Java发展之初设计者们发布规范文档时就刻意把 ...