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");//12345return 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,才是数字0if (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。