【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 ...
随机推荐
- GitHub 上下载代码运行报错 :'The sandbox is not sync with the Podfile.lock\'
问题描述: github下载的Demo,很多时候使用到CocoaPods,有的时候因为依赖关系或者版本问题不能编译运行.出现例如The sandbox is not sync with the Pod ...
- Win8下,以管理员身份启动VS项目
之前一直是先以管理员身份启动VS,然后再打开项目的,比较麻烦,找了好久,总算有一个处理方案了 在Windows7下 通常使用修改属性的方式:在任意快捷方式上右击,选择属性,选择高级,选择以管理员身份启 ...
- Hadoop1.0.3环境搭建流程
0x00 大数据平台相关链接 官网:http://hadoop.apache.org/ 主要参考教程:http://www.cnblogs.com/xia520pi/archive/2012/05/1 ...
- 【Java深入研究】2、JVM类加载机制
一.先看看编写出的代码的执行过程: 二.研究类加载机制的意义 从上图可以看出,类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类 ...
- BZOJ [HAOI2011]防线修建(动态凸包)
听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...
- Linux下自动备份MySQL
使用expect和mysqldump备份 expect expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预. 例如,执行shell脚本的过程中,需要输入用户名.密码 ...
- ARP攻击
ARP攻击,是针对以太网地址解析协议(ARP)的一种攻击技术,就是通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞.此种攻击可让攻击者取得局域网上的数据封包甚至 ...
- 关于c# 基础运算符的应用
运算符 分为5种 1 算数预算符 +,-,*,/,分别为加减乘除 ++为加1,--为减1, 前++ 后++ 的区别 int a = 10, b = a++; Console ...
- HTML中鼠标移动过去变换
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Jquery基本用法
今天下午讲了Jquery的基本用法:在用Jquery方法时,首先要引用Jquery文件: <script src="jquery-1.11.2.min.js">< ...