[C语言]超详细的进制转化你必需了解的知识

[C语言]超详细的进制转换你必需了解的知识

1.求解前需知:

①在c语言中,可以表达的进制有8进制,10进制,16进制,唯独不可以表示的就是2进制。(标准c语言是不支持2进制写法的,但是有些编译器自己进行了扩展,可以支持2进制数字)。

2.c语言中如何表达8进制:

♞8进制整数:由 0~7 个数字组成,使用时必须以数字0开头。

//合法的8进制数
int a = 066//换算成10进制为54
int b = -066//换算成10进制为-54
int c = 0177777//换算成10进制为65535 这个数字有特殊意义(无符号整数能表示的数范围是0-65535)
//不合法的8进制数
int d = 666//无0前缀,相当于10进制
int e = 068//8进制中不能含有8这个数字
int f = 01a//a不是有效的8进制数
int g = 06A//A不是有效的8进制数

♞8进制的转义字符

转义字符表示的意义输出结果
\d、\dd或\ddd(其中d)代表一个8进制数字1-3位8进制所代表的字符与该8进制对应的字符

转义字符主要用于表示那些用一般字符不便表示的控制代码,如/101表示之母A(1×8²+1×8¹+1×8º=65,A的ASCⅡ码值为65)。

♞8进制printf()和scanf()要注意的事项

函数类型格式字符说明
printf()o以8进制无符号形式输出整数(不输出数据前缀0)
scanf()o用来输入无符号的8进制整数,数据前缀0可以有也可以没有

♞8进制与2进制的关系

我们知道2³=8,也就是说三位2进制可以表示一位8进制,这么说可能有点抽象,看下面的图解(图2.1)

8进制转换

当然,你也可以直接拿66除以8,求余在倒序出来呀。都可以的,嘿嘿。

3.c语言中如何表达10进制:

♘10进制整数,由数字0~9个数字组成,没有数据前缀,不能以0开头(不然就和前面的8进制数字矛盾了)。数字前可带正负号。

//合法的10进制数
int a = 666int b = -666int c = +666

♘10进制printf()和scanf()要注意的事项

函数类型格式字符说明
printf()d以带符号的十进制形式输出整数(正数不输出符号)
scanf()d用来输入有符号的十进制数
scanf()u用来输入无符号的十进制数
scanf()ld用来输入有符号的长整形数据

为了区分有符号和无符号呢,这里借鉴了一道题目来看,顺便可以回顾一下==数据类型的自动转换(==参考文献:李春葆,李筱驰,直击招聘,程序员面试C语言深度解析,清华大学出版社,2018)

题目

♘各种数据的高低顺序

在这里插入图片描述

4.c语言如何表达16进制

♜16进制整数:由数字0~9和字母A ~ F(a ~ f)总共十六个数字和字母组成,以0X或0x为数据前缀。

//合法的16进制数
int a = 0X66;//转换为10进制为102
int b = 0X6F;//转换为10进制为111
int c = 0xf6;//转换为10进制为246
//不合法的16进制数
int d = 0xg6;//最大字母不能超过f或F

♜16进制的转义字符

转义字符表示的意义输出结果
\xhh(其中h)代表一个16进制数字1-2位16进制所代表的字符与该16进制对应的字符

转义字符主要用于表示那些用一般字符不便表示的控制代码,如/X0A表示之母A(0×16¹+10×16º=10,换行符的ASCⅡ码值为10)。

♜16进制printf()和scanf()要注意的事项

函数类型格式字符说明
printf()x,X以16进制无符号形式输出整数(不输出数据前缀0x)用小写字母x,则输出的16进制数以a~f形式输出,用大写字母X, 则输出的16进制数以A~F形式输出
scanf()x,X用来输入无符号的16进制整数(大小写作用相同)

♜16进制与2进制的关系

我们知道2 4=16,也就是说四位2进制可以表示一位8进制,根据上面的8进制与二进制的关系,我们继续补充一张图就可以解释清楚:
16进制转换

取巧做进制转换

这里土豆哥在补充一个小数2进制转换的小技巧,先给一道例题,让我们对比一下常规与如何取巧的做法

在这里插入图片描述

其实就是根据二进制独有的0和1的位置关系代表独有的数字来确定的,希望你可以多看几遍上面的动态图感受一下这种做法的魅力呀

5.如何用c语言实现进制转换(代码解释与方法实现):

在c语言中,总共有三种进制,按统计的方法总共有6种进制转换情况。

//分别为10转8, 8转10,10转16,16转10,8转16,16转8这具体的六种情况
//接下来一一描述,希望你能耐心的看下去。

①16进制转10进制

思路:因为数组的取法是从左往右取的,但是数字的最高位正好在最右边,根据位权的关系,我们知道越是高位,就是要成上更多的16,所以我们每取一位数,就乘上16,这样每取一位数字,总乘积就乘上16,正好符合需求,然后根据16进制的特点,判断取的数是在0~9之间还是在A ~ Z之间(a ~ z之间),因为是字符串数组,在减去相应的ASCⅡ码值即可。 理论存在,代码走起!!!

char po1[i];
int num = 0;
for(i=0;po1[i]!=0;i++)
{
    if (po1[i]>='0' && po1[i]<='9')
        num = num*16 + po1[i] -'0';//有些时候你可能会看到减去48的,是因为字符0的ASCⅡ码为48.
    else if(po1[i]>='A' && po1[i]<='Z')
        num = num*16 + po1[i] -'A'+10;//请记住A的ASCⅡ码值为65
     else if(po1[i]>='a' && po1[i]<='z')
        num = num*16 + po1[i] -'a'+10;//请记住a的ASCⅡ码值为97,与大写字母的ASCⅡ码值差32。
}

在真正调用函数的时候还需要在字符串数组后添加’/0’,别忘了!!

②10进制转16进制

思路:将数字m不断除16取余(若余数超过9,还要进行字符转换,10变成a或A,11变成b或B),直到商为零,将全部余数反序即得到结果,即最后得到的余数在最高位。利用循环做除法即可,理论存在,代码走起!!!

void po2(char a[],int m)
{
	int r,i,len = 0;
    char temp;
    while (m > 0)
    {
        r=m%16;
        if (r<10)
        {
            a[len] = r +'0';
        }
        else if(r>='A' && r<='Z')
        {
            a[len] = r+ 'A' -10;
        }
        else if(r>='a' && r<='z')
        {
             a[len] = r+ 'a' -10;
        }
        m/=16;
        ++len;
    }
    a[len] = '\0';//在生成的字符串数组a后加入结束标记
    for(i=0;i<len/2;++i)//翻转数组
    {
        temp = a[i];
        a[i] = a[len -1 -i];
        a[len -1 -i] = temp;
    }

}

③10进制转8进制

思路:与上面的10进制转16进制是很类似的,也是将数字m不断除8取余,直到商为0,最后反序即可。理论存在,代码走起。

void po3(char a[],int m)
{
    int r,len=0;
    while(m>0)
    {
       r =m%8;
       a[len] = r+'0';
       m /= 8;
       i++;
    }
    x[i]='\0';
    for(i= len -1;i>=0;i--)
    {
        printf("%c",a[i]);
    }
    
}

④8进制转10进制

思路:与上面的16进制转10进制相同

char po3[i];
int num = 0;
for(i=0;po3[i]!='\0';i++)
{
        num = num*8 + po1[i] -'0';
    else 
        printf("您输入的数字有误,请重新输入");
}

对于8进制转16进制还有16进制抓8进制,都是要通过10进制这个中间值来完成的,就是将上述代码块进行新的拼接就可以得到你想要的功能啦。

⑤利用辗转相除法实现进制转换:

(先挖个坑,如何利用指针实现进制转换的方法,辗转相除是个不错的选择)

10进制转16进制

#include <stdio.h>
void  main()
{
	int n,b[20],i=0,j;
	printf("输入一个正整数:" );
	scanf("%d",&n);
	while(n>0{
		b[i++]=n%16;
		n/=16;
	}
	printf("对应的十六进制数为:");
	j=i-1;
	do
	{
		if(b[j]<=9)
			printf("%d",b[j] );
		else
		{
			switch(b[j])
			{
				case 10:printf("A");break;
				case 11:printf("B");break;
				case 12:printf("C");break;
				case 13:printf("D");break;
				case 14:printf("E");break;
				case 15:printf("F");break;
			}
		}
		j--;
	}while(j>=0);
	printf("\n");
}

运行结果

在这里插入图片描述

如果看到这里,真的是辛苦你啦!!!如果觉得有帮助的话,请给土豆哥点个赞哟,嘻嘻!!!

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

土豆哥666

感谢你的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值