库函数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。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!