库函数atoi的功能及模拟实现

atoi函数的功能

int atoi(const char * str)    参数是字符指针,函数值是转换后的int型数据。使用时要包含头文件stdlib.h。

atoi函数的功能是:跳过不可见(空白)字符(如空格、换页\f、换行\n、回车\r、制表符\t、垂直制表符\v),碰到正负号或者数字开始转换,转换到非数字字符为止。

即将字符串表示的数字转化为整型。

例如:
输入:"   326"     输出:326
输入:"   +333"    输出:333
输入:"   -333"    输出:-333

atoi函数的使用实例

#include<stdio.h>
#include<stdlib.h>

int main()
{
	char ch[] = "		12345";
	int ret = atoi(ch);
	printf("%d");//12345
	return 0;
}

 atoi函数的模拟实现

#include<stdio.h>
#include<assert.h>
#include<ctype.h> //isspace:判断是否为空格/回车/制表符   isdigit:判断该数字是否为字符数字
#include<stdlib.h>//atoi
enum State
{
	VAILD,
	INVAILD
}Sta = INVAILD;//创造全局枚举变量,默认为非法,考虑传入变量可能为非法

int my_atoi(const char* str)
{
	assert(str);
	if (*str == '\0')    //无效字符串,仅有一个\0
	{
		return 0;
	}
	while (isspace(*str))//跳过空格符
	{
		str++;
	}
	int flag = 1;        //判断是正负数的标志
	if (*str == '+')
	{
		flag = 1;
		str++;
	}
	else if (*str == '-')
	{
		flag = -1;
		str++;
	}
	long long ret = 0;  
	while (*str != '\0')
	{                   
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');//减去字符0,才是数字0
			if (ret > INT_MAX || ret < INT_MIN)  //INT_MAX == 2^32-1 INT_MIN == -2^32 字符表示的数字超过INT变量的范围
			{
				return 0;
			}
		}
		else
		{
			return (int)ret;//强制类型转化为int(函数的返回值是int)
		}
		str++;
	}
	if (*str == '\0')
	{
		Sta = VAILD; //正常转换完了,到末尾的 \0
	}
	return (int)ret;

}
int main()
{
	char arr[20] = "1234";
	int ret = my_atoi(arr);
	if (Sta == VAILD)
	{
		printf("合法转换:%d\n", ret);
	}
	else if (Sta == INVAILD)
	{
		printf("非法转换:%d\n", ret);
	}
	return 0;
}

字符分类函数

C语⾔中有⼀系列的函数是专门做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使用都需要包含⼀个头⽂件是 ctype.h

字符与数字的相互转化

字符'0'~'9'的ASCII码分别是47~57。

字符转数字

1 == '1' -'0' //1 == 48 - 47

2 == '2' -'0' //2 == 49 - 47

数字转字符

由上式换一下项即可

'1' == 1+ '0' //48 == 1 + 47

'2' == 2+ '0' //49 == 2 + 47

ret用long long变量接收的原因

long long在16位/32位/64位环境下都是8个字节,比int的字节数要多,可以防止数据溢出。

如果用int表示的话,当要表示的数据是-2^32()时(代码表示过程:2^32 --> (-1)* 2^32)
表示2^32时int变量会产生溢出,因为int的最大值为2^32-1,如果int i = 2^32该数据就会溢出为0,那么-2^32就变成0*(-1)等于0了。而用8个字节的long long 接收就不会溢出,最后模拟函数再强制转换为int变量即可。
其实也可以用-2^32 * (+/-1)来得到-2^32或+2^32(直接溢出为0),因为Int的最小值为-2^32。详见下面库函数的实现。

库函数的实现

注意点

1.库函数用到了switch来代替if else的判断,当检测到 '-' 时,neg=1(表示负数),因为没有break,switch会被击穿,继续执行s++(指针+1)。当检测到 '+' 时,switch直接执行s++(指针+1)。

2.库函数设计的比较巧妙,没有使用 负数=正数*(-1) 的思路,故也不需要用一个比较大的数来接收数据。而是采用 负数=负数、正数=负数*(-1)的思路,因为int型变量负数的最小值是-2^32,故用负数表示正数不存在溢出的情况。例:-123  n = -1 ---> - 10 - 2 = - 12 ---> -120 - 3 = -123

123  n = -1 ---> - 10 - 2 = - 12 ---> -120 - 3 = -123 ---> -123*(-1)=123。

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值