c++二进制转十进制_C/C+学习笔记:C语言实现任意进制转换,代码全解析!

974e06c5-4c13-eb11-8da9-e4434bdf6706.png


问题描述
给定一个 M 进制的数 x,实现对 x 向任意的一个非 M 进制的数的转换。
问题分析
掌握不同数制间的转换关系是解决问题的关键,这里所说的数制一般包括二进制、八进制、十六进制及十进制。除了不同的数制还有下面几个必须要了解的概念。
基数:在一种数制中,只能使用一组固定的数字来表示数的大小,这组固定的数字的个数就称为该计数制的基数(Base)。例如十进制的基数为10,二进制的基数为2等。
权:又称为位权或权值,即每一个数位都有一个固定的基值与之相对应,称之为权。如十进制的个位对应的权值为1(100),十位对应的权值为10(101),百位对应的权值为100(102)。对于一个 M 进制的数来说,小数点左边各位上对应的权值从右到左分别为基数的0次方、基数的1次方、基数的2次方等,对于小数点右边各位上对应的权值从左到右分别为基数的-1次方、基数的-2次方等。
二进制、八进制、十六进制向十进制转换:按权展开相加。
十进制转换成二进制、八进制、十六进制:整数部分除以基数取余数(取余的方向为从后向前);小数部分乘以基数取整数(取整的方向为从前向后)。
二进制、八进制、十六进制相互转换:先转换成十进制再转换成其他进制;或者按照其对应关系进行转换(三位二进制数对应一位八进制数,四位二进制数对应一位十六进制数)。本例题按照前一种转换方式进行编程。
算法设计
十六进制是由 0~F 这一组固定的数字来表示,所以釆用字符数组进行存储。在进行输入输出时数组元素都是以字符的形式存在的,但是在进行数制转换时数组元素又以数值的形式存在,程序中用两个自定义函数 char_to_number 和 number_to_char 来实现字符与其对应数值之间的转换。
在执行程序时可以输入多组数据来验证程序的正确性,以前的程序都是多次运行,输入不同的数据来实现。对程序稍做改进,只运行一次程序但可以输入多组数据进行验证。解决这个问题只需要加一层循环,如果循环条件为真则继续输入数据,否则退出。循环条件为真即表达式的值不为0,这样可以声明一个变量假设为 flag,利用语句 while(flag) 来进行控制,当 flag 的值为1时可以接着输入,若为0则结束循环。
下面是完整的代码:


#include
#define MAXCHAR 101  /*最大允许字符串长度*/
int char_to_num(char ch);  /*返回字符对应的数字*/
char num_to_char(int num);  /*返回数字对应的字符*/
long source_to_decimal(char temp[], int source);  /*返回由原数转换成的10进制数*/
int decimal_to_object(char temp[], long decimal_num, int object);  /*返回转换成目标数制后字符数组的长度*/
void output(char temp[], int length);  /*将字符数组逆序打印*/
int main()
{
int source;  /*存储原数制*/
int object;  /*存储目标数制*/
int length;  /*存储转换成目标数制后字符数组的长度*/
long decimal_num;  /*存储转换成的10进制数*/
char temp[MAXCHAR];  /*存储待转换的数值和转换后的数值*/
int flag = 1;  /*存储是否退出程序的标志*/
while(flag)  /*利用输入的flag值控制循环是否结束*/
{
printf("转换前的数是:");
scanf("%s", temp);
printf("转换前的数制是:");
scanf("%d", &source);
printf("转换后的数制是:");
scanf("%d", &object);
printf("转换后的数是:");
decimal_num = source_to_decimal(temp, source);
length = decimal_to_object(temp, decimal_num, object);
output(temp, length);
printf("继续请输入1,否则输入0:");
scanf("%d", &flag);
}
return 0;
}
/*将字符转换成数字*/
int char_to_num(char ch)
{
if(ch>='0' && ch
return ch-'0';  /*将数字字符转换成数字*/
else
return ch-'A'+10;  /*将字母字符转换成数字*/
}
char num_to_char(int num)
{
if(num>=0 && num
return (char)('0'+num-0);  /*将0~9之间的数字转换成字符*/
else
return (char)('A'+num-10);  /*将大于10的数字转换成字符*/
}
long source_to_decimal(char temp[], int source)
{
long decimal_num = 0;  /*存储展开之后的和*/
int length;
int i;
for( i=0; temp[i]!='0'; i++ );
length=i;
for( i=0; i
decimal_num = (decimal_num*source) + char_to_num(temp[i]);
return decimal_num;
}
int decimal_to_object(char temp[], long decimal_num, int object)
{
int i=0;
while(decimal_num)
{
temp[i] = num_to_char(decimal_num % object);  /*求出余数并转换为字符*/
decimal_num = decimal_num / object;  /*用十进制数除以基数*/
i++;
}
temp[i]='0';
return i;
}
void output(char temp[], int length)
{
int i;
for( i=length-1; i>=0; i--)  /*输出temp数组中的值*/
printf("%c", temp[i]);
printf("");
}

运行结果:

9a4e06c5-4c13-eb11-8da9-e4434bdf6706.png
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

第1章 声明初始化 基本类型 1.1 我该如何决定使用哪种整数类型? 1.2 为什么不精确定义标准类型的大小? 1.3 因为C语言没有精确定义类型的大小,所以我一般都用typedef定义int16int32。然后根据实际的机器环境把它们定义为int、short、long等类型。这样看来,所有的问题都决了,是吗? 1.4 新的64位机上的64位类型是什么样的? 指针声明 1.5 这样的声明有什么问题?char*p1,p2;我在使用p2的时候报错了。 1.6 我想声明一个指针,并为它分配一些空间,但却不行。这样的代码有什么问题?char*p;*p=malloc(10); 声明风格 1.7 怎样声明定义局变量最好? 1.8 如何在C中实现不透明(抽象)据类型? 1.9 如何生成“半局变量”,就是那种只能被部分源文件中的部分函访问的变量? 存储类型 1.10 同一个静态(static)函或变量的所有声明都必需包含static存储类型吗? 1.11 extern在函声明中是什么意思? 1.12 关键字auto到底有什么用途? 类型定义(typedef) 1.13 对于用户定义类型,typedef#define有什么区别? 1.14 我似乎不能成功定义一个链表。我试过typedefstruct{char*item;NODEPTRnext;}*NODEPTR;但是编译器报了错误信息。难道在C语言中结构不能包含指向自己的指针吗? 1.15 如何定义一对相互引用的结构? 1.16 Struct{ }x1;typedefstruct{ }x2;这两个声明有什么区别? 1.17 “typedefint(*funcptr)();”是什么意思? const限定词 1.18 我有这样一组声明:typedefchar*charp;constcharpp;为什么是p而不是它指向的字符为const? 1.19 为什么不能像下面这样在初始式组维度值中使用const值?constintn=5;inta[n]; 1.20 constchar*p、charconst*pchar*constp有什么区别? 复杂的声明 1.21 怎样建立非常复杂的声明?例如定义一个包含N个指向返回指向字符的指针的函的指针的组? 1.22 如何声明返回指向同类型函的指针的函?我在设计一个状态机,用函表示每种状态,每个函都会返回一个指向下一个状态的函的指针。可我找不到任何方法来声明这样的函——感觉我需要一个返回指针的函,返回的指针指向的又是返回指针的函……,如此往复,以至无穷。 组大小 1.23 能否声明传入组大小一致的局部组,或者由其他参指定大小的参组? 1.24 我在一个文件中定义了一个extern组,然后在另一个文件中使用,为什么sizeof取不到组的大小? 声明问题 1.25 函只定义了一次,调用了一次,但编译器提示非法重声明了。 *1.26 main的正确定义是什么?voidmain正确吗? 1.27 我的编译器总在报函原型不匹配的错误,可我觉得没什么问题。这是为什么? 1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 1.29 为什么我的编译器不允许我定义大组,如doublearray[256][256]? 命名空间 1.30如何判断哪些标识符可以使用,哪些被保留了? 初始化 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个局变量初始值为“零”,它可否作为空指针或浮点零? 1.32 下面的代码为什么不能编译?intf(){chara[]="Hello,world!";} *1.33 下面的初始化有什么问题?编译器提示“invalidinitializers”或其他信息。char*p=malloc(10); 1.34 chara[]="stringliteral";char*p="stringliteral";初始化有什么区别?当我向p[i]赋值的时候,我的程序崩溃了。 1.35 chara{[3]}="abc";是否合法? 1.36 我总算弄清楚函指针的声明方法了,但怎样才能初始化呢? 1.37 能够初始化联合吗? 第2章 结构、联合枚举 结构声明 2.1 structx1{ };typedefstruct{ }x2;有什么不同? 2.2 这样的代码为什么不对?structx{ };xthestruct; 2.3 结构可以包含指向自己的指针吗? 2.4 在C语言中用什么方法实现抽象据类型最好? *2.5 在C语言中是否有模拟继承等面向对象程序设计特性的好方法? 2.6 为什么声明externf(structx*p);给我报了一个晦涩
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值