【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 ...
随机推荐
- 从C#到TypeScript - function
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- java学习书籍推荐
1. Java 语言基础 谈到Java 语言基础学习的书籍,大家肯定会推荐Bruce Eckel 的<Thinking in Java >.它是一本写的相当深刻的技术书籍,Java 语言基 ...
- Linux TCP连接数修改
一. 文件数限制修改 (1) vi /etc/security/limits.conf * soft nofile 10240 * hard nofile 10240 ...
- javascript深入理解js闭包(转载)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- sql server数据库备份压缩拷贝实例
--数据库备份压缩拷贝实例:前提要安装RAR压缩软件--声明变量declare @day varchar(10),@dbname varchar(20),@filename varchar(100), ...
- MyBatis 源码分析——类型处理器
官网上面讲到:无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型.那 ...
- 3步轻松搭建Unity3d安卓开发环境
之前写过一个Untiy3d安卓开发环境的配置教程,那是我第一次学习配置安卓开发环境,互联网上的信息良莠不齐,自己当时也不懂,配置步骤麻烦的一塌糊涂,现在见的多了,也会的多了,配置安卓开发环境变得非常容 ...
- 交互神器 Facebook Origami
最近用到了一个非常强大的工具,这是一款由 facebook 出品的原型设计软件,老规矩我们先来看一下效果.大家也可以先进去官网看看效果Origami 官网 scroll.gif swipe.gif O ...
- CoreAnimation 图层几何学
CoreAnimation 图层几何学 博客园MakeDown支持不佳,如有需要请进GitHub 图层几何所讲主要是有关图层的位置,尺寸等几何类属性. 布局 在UIView中与位置,尺寸有关的属性有 ...
- iOS项目之同时点击多个按钮解决方案
自己的项目完成后,在测试中出现了一个情况,同时点击界面中的多个按钮,会跳转多个界面.然后又看了看别的app,发现也有这样的情况, 如图 上面是我手机上美团app的截图,上面的分类同时选择多个时,只能跳 ...