首页 > 代码库 > 【C语言】模拟实现atoi函数
【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=http://www.mamicode.com/%d,state=",my_atoi("123456789")); PrintState();//正常 printf("value=http://www.mamicode.com/%d,state=",my_atoi("-123456789")); PrintState();//正常 printf("value=http://www.mamicode.com/%d,state=",my_atoi("-123456789sassa")); PrintState();//正常,遇到字母终止 printf("value=http://www.mamicode.com/%d,state=",my_atoi(" -123456789sassa")); PrintState();//正常,前面带空格 printf("value=http://www.mamicode.com/%d,state=",my_atoi("")); //////////////异常情况///////// printf("\n\n"); PrintState();//异常:空字符串 printf("value=http://www.mamicode.com/%d,state=",my_atoi("123456789123456789"),flag); PrintState();//异常:正溢出 printf("value=http://www.mamicode.com/%d,state=",my_atoi("-123456789123456789"),flag); PrintState();//异常:负溢出 printf("value=http://www.mamicode.com/%d,state=",my_atoi("dasdsa"),flag); PrintState();//异常:无法转换 } int main(){ FunTest(); return 0; }
彩蛋:在写测试函数时,有一件事,始终不得其解,一开始我将测试代码写成了这样:
void FunTest(){ printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi("123456789"),flag);//正常 printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi("-123456789"),flag);//正常 printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi("-123456789sassa"),flag);//正常,遇到字母终止 printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi(" -123456789sassa"),flag);//正常,前面带空格 printf("\n\n\n"); printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi(""),flag);//异常:空字符串 printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi("123456789123456789"),flag);//异常:正溢出 printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi("-123456789123456789"),flag);//异常:负溢出 printf("value=http://www.mamicode.com/%d,state=%d/n",my_atoi("dasdsa"),flag);//异常:无法转换 }
测试时,发现一件诡异的事情!!!!!!!
结果输出是这样:
value=http://www.mamicode.com/123456789,state=0>
我还特意跟进函数体内看,发现全局变量flag确实被改为了1,但为什么输出的是0呢???
正当我百思不得其解时,突然想到printf函数的调用约定是_cdel!!!!
因此,_cdel调用约定,是将参数由右向左压栈,因此它先将flag压栈,然后再执行my_atoi函数,在my_atoi函数体内修改了全局变量flag.....
所以,最终输出了0!
因此,才有了最终代码!
【C语言】模拟实现atoi函数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。