| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2639 人关注过本帖, 1 人收藏
标题:关于itoa()函数的实现,想和大家轻松的聊聊,我只是在15楼把自己知道的一个比 ...
取消只看楼主 加入收藏
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
结帖率:98.63%
收藏(1)
已结贴  问题点数:20 回复次数:8 
关于itoa()函数的实现,想和大家轻松的聊聊,我只是在15楼把自己知道的一个比较新的实现又发上来了,附加了一点自己的想法,没太大改变
今天突然看到一篇关于itoa()函数实现的文章,很有意思,

好像itoa() 不是ANSI C标准的函数,man 一下itoa,果然找不到

这是一个把整数转为文字列的函数,比如itoa(10, 8)

意思就是按8进制转换10,变成12

据说itoa()早期的实现是出现在google group里

是一个叫Robert Jan Schaper 的洋人写的,如下
程序代码:
char* itoa(int val, int base){
    
    static char buf[32] = {0};
    
    int i = 30;
    
    for(; val && i ; --i, val /= base)
    
        buf[i] = "0123456789abcdef"[val % base];
    
    return &buf[i+1];
    
}


乍看上去不明折什么意思,仔细想想觉得真的很聪明

buf[]里能存32个字符,正好是32位的int

这里的 i 还真让我想了一会儿, 原来下标最多31,返回的时候用的是return &buf[i+1]

所以i 最多可以从30开始......

在我这菜鸟看来,感觉

buf[i] = "0123456789abcdef"[val % base];

 这句写的好漂亮啊(肯定有大鸟在说你看这菜鸟又在大惊小怪了)

一般在用这个函数的时候形式好像都是

char *itoa(int val, char *buffer, int radix)
上面的代码却用了static

但感觉还是多接受一个char * buffer参数比较好吧

大家有没有更多关于itoa()实现了, 拿出来晒晒吧!

[ 本帖最后由 madfrogme 于 2012-1-19 19:53 编辑 ]
搜索更多相关主题的帖子: 函数 google Robert 
2012-01-17 23:18
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 2楼 beyondyf
嗯,谢谢斑竹指正,也许正因为不是标准,所以个个编译器不一样吧
我的gcc里还真的没有艾
$ gcc -o test test.c
/tmp/ccRgTNsO.o: In function `main':
test.c:(.text+0x2d): undefined reference to `itoa'
collect2: ld returned 1 exit status
wzj@U10:~$

The quieter you become, the more you can hear
2012-01-17 23:35
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 5楼 beyondyf
哇塞,这个想法!
晚安!

The quieter you become, the more you can hear
2012-01-17 23:44
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 5楼 beyondyf
在斑竹的建议下另一个itoa的另一个实现新鲜出炉了
程序代码:
void itoa(int val, char *buff, int radix) {
    
        int sign;
    
        static char num[]=
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char *wchar = buff;        /*通过wchar 指针来存储*/

    div_t res;                        /* 这是新学到的本领,div_t构造体里存的是做除法后整数部分和商*/

    if ((sign = val) < 0)        /* 判断正负*/

        val = -val;                

    if(radix > 62 || radix < 2) 

        *wchar = '\0';

        return;

    do {

        res = div(val,radix);   /* 一开始只写了 div(val, radix) ,果然错误 */

        *wchar++ = num[res.rem];

    }while(val = res.quot) ;  /* 一开始只写了 while(res.quot),才发现segmentation fault来自这里*/

    if(sign < 0)

        *wchar++ = '-'; /* 一开始犹豫把 '-'放在最前面,才发现应该放在最后面,因为求出来的字符也是被倒着存的,所以这个版本里要用到strreverse()

    *wchar = '\0';

    strreverse(buff,wchar-1); /* 一开始写的是strreverse(0, wchar -1) ,才发现得不出結果,得是(buff,wchar-1) */
}

void strreverse(char *beg, char *end) {
    char temp;
    while(end > beg)
        temp = *end, *end-- = *beg, *beg++ = temp;
}    


睡前最后一贴,Base64星期天看~~

The quieter you become, the more you can hear
2012-01-18 00:48
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
貌似传送伊妹儿的时候只能用文本形式,
所以图像之类的二进制就要被转换,
base64就是其中一种方式啊
原来如此,很有意思的样子,
还想再详细了解

The quieter you become, the more you can hear
2012-01-18 01:06
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 11楼 小鱼儿c
谢谢夸奖,晚上回来贴一个很新的itoa()实现哦

The quieter you become, the more you can hear
2012-01-19 09:31
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 10楼 sd6862959
恩,我还没看那本书,你是说itoa()

还是base64?

The quieter you become, the more you can hear
2012-01-19 09:37
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
回复 9楼 俺是小c
是啊,一起学习

The quieter you become, the more you can hear
2012-01-19 09:39
madfrogme
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
想把自己知道的itoa()函数最后一个版本也贴出来,当然会附上自己的理解

如果看过前面代码的仁兄我只想说一下对

*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];

这句话的理解
程序代码:
char* itoa(int value, char* result, int base) {
        
        if (base < 2 || base > 36) { *result = '\0'; return result; }
    
        char* ptr = result, *ptr1 = result, tmp_char;
        
                int tmp_value;
    
        do {

            tmp_value = value;

            value /= base;

            *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];

        } while ( value );
    
        // Apply negative sign

        if (tmp_value < 0) *ptr++ = '-';

        *ptr-- = '\0';

        while(ptr1 < ptr) {

            tmp_char = *ptr;

            *ptr--= *ptr1;

            *ptr1++ = tmp_char;
        }
        return result;
    }

作者将字符串弄成了“z-a9-0-9a-z" 这么一长串是为了处理负数的

下标35是指向 0

方括号中的下标 temp_value - value*base

比如 -9 除以 8 等于 -1 余 -1

仔细一看其实就是求余数(%),难道计算机运行 “减法+乘法” 的速度都比 取余数快???

还有一个感受就是自己对do while 循环有一种本能的抗拒,感觉有种“先斩后奏“的感觉,

让自己写的话估计是困难,只是多看别人的代码收获很大

The quieter you become, the more you can hear
2012-01-19 19:49
快速回复:关于itoa()函数的实现,想和大家轻松的聊聊,我只是在15楼把自己知道的 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019814 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved