C程序设计语言(K&R 第二版):练习3-5

题目

编写函数itob(n, s, b),将整数n转换为以b为底的数,并将转换结果以字符的形式保存到字符串s中。例如itob(n, s, 16)把整数n格式化成十六进制整数保存在s中。

自我解答:

参照练习3-5中的思路,以b为底即代表不断对b求余数,需要注意的一点是考虑十六进制的情况,当余数大于9是用字母a~f来替代。解答如下: 

#include <stdio.h>
#include <string.h>

#define abs(x)      ((x) < 0 ? -(x) : (x))

void reverse(char s[]);

/* itoa: convert n to characters in s - modified    */ 
void itob(int n, char s[], int b)
{
    int i, sign, c;
    
    sign = n;       /* record sign                  */
    i = 0;
    do              /* generate digits in reverse order */
    {
        c = abs(n % b);
        s[i++] = c > 9 ? (c + 'a' - 10) : (c + '0'); /* get next digit  */
    }
    while((n /= b) != 0);          /* delete it        */
    if(sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

void reverse(char s[])
{
    int c, i, j;
    
    for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

int main()
{
    char s1[20] = {'\0'};
    int a = -214748367;
    itob(a, s1, 16);
    printf("%s\n", s1);
}

 运行结果:-ccccccf

参考答案:

/* itob: convert n to characters in s - based b    */ 
void itob(int n, char s[], int b)
{
    int i, j, sign;
    void reverse(char s[]);
    
    if((sign = n) < 0)      /* record sign          */
        n = -n
    i = 0;
    do{                     /* generate digits in reverse order */
        j = n % b;          /* get next digit  */
        s[i++] = (j <= 9) ? j + '0' : j + 'a' - 10;
    }while((n /= b) > 0);
    if(sign < 0)            /* delete it                        */
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

 我们解答这道练习的思路是:先按逆序生成b进制数的每一位数字,再用函数reverse(参见练习1-19)对字符串s中的字符做一次颠倒而得到最终的结果。因为我们要把整数n转换为一个b进制数,所以我们要用 n % b 依次返回一个0到b-1之间的值并把这个值转换为相应的字符保存到字符串s中。然后再用n /= b调整n的值。只要n/b大于零,这一过程就将一直循环下去。

备注:

参考答案中的解答依然是参考了书中关于itoa的例子的代码,依然会存在不能处理最小负整数的情况。自我解答中是参考了 3-4中改进版本的参考答案的基础上的,所以在处理最小负数的情况依然不会有问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值