|  | 
 
 发表于 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++;
 | 
 评分
查看全部评分
 |