|
发表于 2016-7-12 11:46:32
|
显示全部楼层
atoi
把字符串转换为整数
下面举个例子
假如有一个字符串 "1234" ,要怎么转换成 整数1234呢?
说到这里,知道字符串 "1234" 和 整数 1234 的区别吗?
字符串 "1234" 实际是 字符 '1' '2' '3' '4' 这 4 个字符挨着在内存中存放
假如在内存地址0x10 的位置存放字符 '1',那么就是下面这样
内存地址 0x08 0x09 0x10 0x11 0x12 0x13 0x14
内存中的内容 ... ... '1' '2' '3' '4' ... (...表示任何内容,我们只需要内存地址0x10 ---- 0x13,其他不重要)
所以字符串就是一串字符
在这里还有一个问题,像 字符 '1' '2' '3' '4' 这样的字符如何在内存中存放呢,所以出现了ascii 标准,ascii的知识自己学习,这里不介绍了,给一个地址
http://baike.so.com/doc/7103239-7326232.html
在ascii表中 字符 '1' 是 整数 十六进制的 0x31 也就是十进制的 49
没错,字符其实是整数
那么
内存地址 0x08 0x09 0x10 0x11 0x12 0x13 0x14
内存中的内容 ... ... 0x31 0x32 0x33 0x34 ... (...表示任何内容,我们只需要内存地址0x10 ---- 0x13,其他不重要)
现在预备知识已经足够了,我们来把字符串 "1234" 转换成整数
我们要怎么把 字符串 "1234" 转换成整数呢?
好像不能直接转换,那就分开
这样我们就得到了 4 个字符 '1' '2' '3' '4'
接下来怎么办?
现在换一个思路,找一下规律
我们把整数 1234 转换成 字符串
当然不能直接转换,
好,分开
那么,要如何分呢?
如何把 整数1234,分成 整数1 整数2 整数3 整数4 呢?
在换个思路,如何把 整数1 整数2 整数3 整数4,转换成 1234
这里,我介绍一种方法
1234 = 4 + 3 * 10 + 2 * 100 + 1 * 1000 = 1234
这样我们可以把任意单独的数字(只有一位数的)合并成整数
我们要的就是这个
现在返回,
前面说过字符是整数
那字符串就是整数串了^_^,其实完全可以这样理解
上面的字符串 "1234",其实是 整数 0x31 0x32 0x33 0x34 挨着存放在内存中
现在有一个问题,上面说过,可以把任意单独的数字(只有一位数的)合并成整数
这里的 0x31 0x32 0x33 0x34 并不是单独的数字(只有一位数的)
0x31 是 十进制的 49 , 0x32 是十进制的 50 , 0x33是十进制的 51, 0x34 是十进制的 52
怎么把它们变成1位数又不影响最后的结果呢?
这里我们需要把字符 转换成对应的整数 ,例如 把 字符 '1' 转换成 整数 1
注意,字符 '1' 不是整数 1
它们之间相差 0x30
字符 '1' 是整数 0x31
字符 '0' 是整数 0x30
现在重新把字符串 "1234"转换成整数已经不难了吧
(1.)先把字符串分解成多个字符 '1' '2' '3' '4'
(2.)把字符转换成对应的整数 '1' - '0' = 0x31 - 0x30 = 1 , '2' - '0' = 0x32 - 0x30 = 2 , '3' - '0' = 0x33 - 0x30 = 3 , '4' - '0' = 0x34 - 0x30 = 4, 这里知道为什么要减 '0' 了吧,因为 字符和整数之间相差 0x30 ,而 '0' 正好是0x30, 你完全可以写 '1' - 0x30,不过这样写有一些缺点
(3.)把单独的整数合并 1 * 1000 + 2 * 100 + 3 * 10 + 4 = 1234
现在来讲一下c代码
unsigned long long my_atol(char const *str)
{
unsigned long long ret = 0; // 转换后的结果放在这里,最后返回调用者
int str_len = strlen(str); // 得到字符串的长度, 如果是字符串 "1234" ,str_len == 4,有疑问的话去查一下函数 strlen 的用法
int i = 0; //相当于一个 "指针", 它指向字符串中的某个字符
str_len--; // 数组从 0 开始计数 ,这里的 str_len 是一个最大值
while(1)
{
char current = str[i];
ret = ret * 10 + (current - '0');
if(i == str_len) // i从 0 开始计数,当 i == str_len 时,所有字符已经转换完成
{
break;
}
i++; //指向下一个字符
}
return ret;
}
下面已字符串 "1234" 说一下
char current = str[i];
ret = ret * 10 + (current - '0');
i++; //指向下一个字符
str[0] 是字符 '1'
str[1] 是字符 '2'
str[2] 是字符 '3'
str[3] 是字符 '4'
第零次
char current = str[i]; // current == str[i] == '1' , 因为i == 0
ret = ret * 10 + (current - '0'); //current = '1' , 那么就是 ret = 0 * 10 + ('1' - '0') = 1, 因为 ret 初始化为 0,字符 '1' - '0' = 1,最后 ret = 1
i++; //指向下一个字符, 下一个字符是 '2'
第一次
char current = str[i]; // current == str[i] == '2' , 因为i == 1
ret = ret * 10 + (current - '0'); //current = '2' , 那么就是 ret = 1 * 10 + ('2' - '0') = 12, 因为 ret 在上一次是 1,字符 '2' - '0' = 2,最后 ret = 12
i++; //指向下一个字符, 下一个字符是 '3'
第二次
char current = str[i]; // current == str[i] == '3' , 因为i == 2
ret = ret * 10 + (current - '0'); //current = '3' , 那么就是 ret = 12 * 10 + ('3' - '0') = 123, 因为 ret 在上一次是 12,字符 '3' - '0' = 3,最后 ret = 123
i++; //指向下一个字符, 下一个字符是 '3'
第三次
char current = str[i]; // current == str[i] == '4' , 因为i == 3
ret = ret * 10 + (current - '0'); //current = '4' , 那么就是 ret = 123 * 10 + ('4' - '0') = 1234, 因为 ret 在上一次是 123,字符 '4' - '0' = 4,最后 ret = 1234
i++; //指向下一个字符, 下一个字符是 (下一个是什么我也不知道^_^,其实不会执行到这里,i也不会加1,i依然是3)
第四次 ?
没有第四次
因为 i = 3, str_len = 3,在第三次的if(i == str_len) 结束了while(1)循环,之后返回
while(1)
{
char current = str[i];
ret = ret * 10 + (current - '0');
if(i == str_len) // i从 0 开始计数,当 i == str_len 时,所有字符已经转换完成
{
break;
}
i++; //指向下一个字符
}
现在你明白这个了吗?
value *= 10;
value += *str - '0';
str++; |
评分
-
查看全部评分
|