鱼C论坛

 找回密码
 立即注册
查看: 1842|回复: 7

atoi

[复制链接]
发表于 2016-7-11 14:15:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  在atoi函数中 下面代表的是什么意思啊???              

                value *= 10;
                value += *str - '0';
                str++;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-7-11 17:00:38 | 显示全部楼层
value = vale *10以此类推
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-11 18:19:16 | 显示全部楼层
康小泡 发表于 2016-7-11 17:00
value = vale *10以此类推

我知道啊,但这个公式是为什么呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-7-12 09:49:56 | 显示全部楼层
qq1242009750 发表于 2016-7-11 18:19
我知道啊,但这个公式是为什么呢?

语法啊,这个是,没有为什么啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-12 10:25:51 | 显示全部楼层
康小泡 发表于 2016-7-12 09:49
语法啊,这个是,没有为什么啊

能给我解释这个语法为什么是这样吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-12 11:16:04 | 显示全部楼层
题目的做法是把字符隐式强制转换成int型,即对应的ASCII码,ASCII码中‘3’ = ‘0’ + 3;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-7-12 11:32:38 | 显示全部楼层
*str - '0';//用ASCII码将字符转成数字

如果输入四个字符,例如是'2' '4' '6' '8',
公式的意思就是:
第一次循环2.
第二次循环2*10 +4 == 24;
第三次循环24*10 + 6 == 246;
第四次循环246*10 + 8 == 2468;
循环结束,跳出,返回值2468,猜的,下次最后把整个源码贴出来,然后说明哪个位置不明白,这样会比较好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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++;

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
n0noper + 5 + 5 + 5 楼主这详细的回复,辛苦了!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-27 04:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表