C程序设计语言第二版习题3-5-阿里云开发者社区

开发者社区> 苟哥> 正文

C程序设计语言第二版习题3-5

简介: 编写函数itob(n, s, b) ,用于把整数n转换成以b为基数的字符串并存到字符串s中。例如, itob(n, s, 16) 表示将n转换成16进制数,并存入s中。
+关注继续查看

问题描述

编写函数itob(n, s, b) ,用于把整数n转换成以b为基数的字符串并存到字符串s中。例如, itob(n, s, 16) 表示将n转换成16进制数,并存入s中。

问题分解

  • 主函数main
  • 工具函数reverse(s) ,用来逆置字符串
  • 核心函数 itob(n, s, b)。这道题其实也是习题3-4的一个引申了,我们先来回顾3-4 的itoa函数的实现:
void itoa(int n, char s[])
{
    int sign, i;
    sign = n;
    i = 0;
    do {
        s[i++] = ((sign < 0) ?-(n % 10) : n % 10) + '0'; //负数对10求余仍然是负数
    } while ((n /= 10) != 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

我们知道10进制整数转换成b进制的算法是: 不断用 n 对b进行求余,直到商为0,那么每次求余的结果,从后往前组合一起就是对应的b进制数。因此,itoa 可以看做把整数n转换成10进制数的itob特例,即此时b = 10, 由此我们可以假设itob的实现为:

void itob(int n, char s[], int b)
{
    int sign, i;
    sign = n;
    i = 0;
    do {
        s[i++] = ((sign < 0) ?-(n % b) : n % b) + '0'; //负数对10求余仍然是负数
    } while ((n /= b) != 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

我们检验一下,当b = 2,8,10 时都是满足的,唯独b = 16时会出个问题,因为n % 16 的结果有可能大于9,大于9的时候应该使用字母表示,而不是数字了,因此我们要针对b=16情况做个改进,改进后的代码请看如下代码实现。

代码实现

#include<stdio.h>
​
void itob(int n, char s[], int b);
void reverse(char s[]);
​
int main()
{
        int n = (~0U >> 1) + 1, b = 16;
        char s[100];
        printf("The input number is: %d\n", n);
        itob(n, s, b);
        printf("The output string is: %s\n", s);
        return 0;
}
​
void itob(int n, char s[], int b)
{
    int sign, i, temp;
    sign = n;
    i = 0;
    do {
      temp = sign < 0 ?  -(n % b) : n % b;
      if(temp > 9){
        s[i++] = temp - 10 + 'a';
      }else{
        s[i++] = temp + '0';
      }
    } while ((n /= b) != 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}
​
void reverse(char s[])
{
    int i, j, c;
    for (j = 0; s[j] != '\0'; j++)
        ;
    for (i = 0, j--; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

编译运行

image

由运行结果可看出,原方法得到的结果不是预期的,改造后的得到了正确的结果。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
15 年老兵谈阿里云大规模机器学习实践
  近年来,机器学习技术的发展归因于我们有极其庞大的数据用来训练算法。当企业需要落地大规模机器学习时,往往会面临很多难题,如何解决这些问题?如何系统了解大规模机器学习落地的技巧?其适用场景是什么?InfoQ 希望通过该选题解决这些问题,并推动企业在大规模机器学习方面的实践。本文,InfoQ 有幸采访了阿里云机器学习研究员林伟,听他分享自己的经验和见解。
4 0
JavaScript、PHP、Golang、Haskell、Elixir,哪个才是最佳编程语言?
  在过去的几年里,我有机会尝试了多种不同的编程语言。   我非常喜欢学习不同的语言、方法和范式。我是一个充满好奇心的人,一直对编程语言十分着迷。每种编程语言都是不同的,在本文中,我们来讨论一下以下五大编程语言的优点以及缺点。
3 0
与数据隐私相关的 AI 关键问题
  本文最初发表在 Towards Data Science 博客,经原作者 Alexandros Zenonos 授权,InfoQ 中文站翻译并分享。   隐私不仅是与人工智能有关的问题,也是任何与数据相关的领域普遍关注的问题。隐私是关于人们对其个人数据和基于这些数据所做的决定的控制。
6 0
如果你有拖延症,程序员不如试试这个技巧提升效率?
  要吃掉一头大象,每次吃一口。   ——克雷顿·艾布拉姆斯(Creighton Abrams)   造成拖延的首要原因之一,同时也是造成生产力低下的祸根,就是总是在感慨一个问题:好忙啊,问题好大啊……实际上,你并没有真正试着去解决问题。当我们从任务的全貌来审视任务的时候,它们看起来比真实情况都要大,并且更吓人。   在本文中,我会谈及一个能够帮助你克服拖延的提高生产力的窍门:分解任务。通过将大任务分解为小任务,你会发现自己更有动力去完成它们,也更加稳妥地向着目标前进。
7 0
后端缓存的23个关键关注点(3)
后端缓存的23个关键关注点(3)
5 0
程序员真的是吃青春饭吗?如何面对传说中的 35 岁职业焦虑?
  正走在这条路上的你或许也曾想过这些问题。这一次,力扣邀请到了《高效制胜——程序员面试典型题解》作者吴江(迈克老师),分享他 35 岁跳槽,并拿到了技术负责人 Offer,实现收入增长的故事和面试准备经验。   — 01 —   “35 岁危机”真有那么可怕吗?   在 2018 年快过春节的时候,我们部门突然被通知要开一个会,会上通知我们部门要在明年的这个时候被整体裁掉。我在这家五百强外企已经待了五年,当时虽然有这个预感,但是真的听到正式通知时,不免还是感觉有点震惊。
3 0
Redis Cluster 宕机引发的事故(上)
Redis Cluster 宕机引发的事故(上)导读: Redis官方号称支持并发11万读操作,并发8万写操作。由于优异的性能和方便的操作,相信很多人都在项目中都使用了Redis,为了不让应用过分的依赖 Redis服务,Redis的作用只作为提升应用并发和降低应用响应时间存在,即使Redis出现异常,应用程序也不应该出现提供服务失败问题,对此拍拍信最近安排了一次全环境的Redis Cluster 宕机演练。 本文作者系拍拍信架构负责人朱荣松和拍拍信架构开发工程师许彬,授权“技术锁话”进行发布。
5 0
【Elastic Engineering】Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana
Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana
6 0
Keras之父写给年轻程序员的33条忠告
  代码是一种交流方式,Keras 之父 Fran?ois Chollet 在本文中为我们总结了在开发过程中、API 设计中及软件职业生涯中应该关注哪些要点。原则是形式化的直觉,比原始模式识别适用于更广泛的情况,Fran?ois Chollet 的这份原则清单将带你领略大师的品味。
6 0
+关注
苟哥
脚踏实地,希望不被技术世界淘汰
26
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载