zoukankan      html  css  js  c++  java
  • 【C语言】模拟实现atoi函数

      atoi(表示 ascii to integer)是把字符串转换成整型数的一个函数.

      atoi()函数会扫描参数 nptr字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过isspace( )函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('')才结束转换,并将结果返回。如果 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( '' == *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!='')&&(*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函数状态+
    
    void PrintState(){
    	if(flag){
    		printf("异常
    ");
    	}else{
    		printf("正常
    ");
    	}
    }
    //测试函数
    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("
    
    ");
    	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
    ",my_atoi("123456789"),flag);//正常
    	printf("value=%d,state=%d
    ",my_atoi("-123456789"),flag);//正常
    	printf("value=%d,state=%d
    ",my_atoi("-123456789sassa"),flag);//正常,遇到字母终止
    	printf("value=%d,state=%d
    ",my_atoi("	  -123456789sassa"),flag);//正常,前面带空格
    	printf("
    
    
    ");
    	printf("value=%d,state=%d
    ",my_atoi(""),flag);//异常:空字符串
    	printf("value=%d,state=%d
    ",my_atoi("123456789123456789"),flag);//异常:正溢出
    	printf("value=%d,state=%d
    ",my_atoi("-123456789123456789"),flag);//异常:负溢出
    	printf("value=%d,state=%d
    ",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!

      因此,才有了最终代码!

      

  • 相关阅读:
    Python_字典
    Python_字符串方法
    跳转到新页面,加载过程中加入等待过渡的动态效果
    web项目引入第三方jar包,编译时找不到的问题与及解决方案
    Eclipse的debug按钮介绍
    什么是TCP粘包?怎么解决TCP粘包问题?UDP协议存在粘包问题吗?
    使用Java编写TCP协议发送和接收数据接口
    UUID生成唯一的16位随机数
    如何在父页面中操作/获取iframe页面中的元素?这个小问题折腾了我快半个小时,所以记下来吧!
    如何接收APP的请求,并且如何以json字符串的格式封装响应的数据,然后发送回APP
  • 原文地址:https://www.cnblogs.com/qq329914874/p/6075810.html
Copyright © 2011-2022 走看看