C 用移位法实现二进制转十进制【详解】

首先是理解该方法的理论基础:

1.移位运算符的语法及运算规则

2.函数 scanf() 是从标准输入stdio中读内容的通用子程序(注意是,和c++中的cout一样)

如果不理解,请查阅资料,否则无法理解这个方法

下面进入正题:

假设一个二进制数11,我们都知道它对应的十进制数是3,

大部分人脑中进行了如下的惯性思维式思考:

第一位是1,第二位是2,所以1+2=3

但是如果是一个很长的二进制数呢?习惯了10进制数计算的人必然无法快速算出其十进制值,这是因为这种传统的方法涉及到了算术运算.有算术运算就涉及到数学上的公式,算法,那么有没有一种方法,可以让我们避免采用这种方法,把这种繁琐的步骤交给电脑来算,最后输出结果就行了呢?有的!


假设以下情形:

我们有一个十进制整型数n,n的值是0.于是此时n的二进制形式也是0。

这时,我们要将二进制数11转化成十进制数3,而不使用传统的算数方法(在本案例中传统方法是1+1乘 2的1次方)

移位法的思想既是:

由于int型的n为0,而十进制的0与二进制的0都是0,所以,我们可以对n进行移位,通过移位将n的二进制形式从0变成11,又因为n是int型,所以输出n的时候,是将n作为十进制整型输出的,也就是3。这就完成了二进制到十进制的转换。

PS:n虽然是整型,但当对n使用移位运算符时,编译器是将n看成一个二进制数,再移位的,移位后返回int型结果,也就是说,对十进制数使用移位运算符包含两次隐式转换,第一次是将n变成二进制数,第二次是将移位后的n变回十进制数.

举例:通过移位将11转化成10进制数3

首先,我们有一个初始的int型数n,n无论十进制值还是二进制值都为0,如何将二进制0变成二进制11呢?将11从左到右一个数字一个数字的读取,首先读取到第一个1,然后将n左移一位(由于此时n值为0,所以移位后n仍然是0),然后把刚才读取的1加到n上,此时n的二进制值变成1了;然后读取第二个1,然后将n左移一位(此时n的值为1,所以移位后n是10),然后把刚才读取的1加到n上,此时n的二进制值就变成11了;OK,n的二进制形式已经完成了由0到11的转变,此时直接以int型输出n,就得到了3。

以上过程中,我们仅仅将n的二进制形式通过移位变成了11,至于二进制11怎么变成十进制3的,这个过程我们不需要知道,因为我们把这个工作交给了编译器来处理。

以下是代码:

#include<stdio.h>
int main(void)
{int n=0;
 char c;
 printf("请输入一个二进制数:");
 scanf("%c",&c);     /*由于c为char型,所以scanf一次只能将一个数字储存在c中,剩下的数字和敲击的回车,仍然在输入流中,等待while循环体中的scanf读取*/
 while(c=='0'||c=='1')  /*该循环体的作用是将n的二进制形式0通过移位转变成以上输入的二进制数*/
   {printf("%c",c);  /*参考第12行*/
    n=(n<<1)+c-'0';     /*一次(每读取一个数字)向左移一位,c为每一次读取的数字的ASCII值*/
    scanf("%c",&c);    /*重复循环读取输入流中的数字,直到遇到回车,循环终止*/
   }
 printf("的十进制数=%d\n",n);     /*将转变完后的二进制数以十进制整型输出,得到结果("的"前面为刚才输入的二进制数,由第8行的printf输出)*/
 return 0;
}
对于第9行中c-'0'的解释:

c是字符型,所以c储存的是字符的ASCII值,而不是这个字符,'0'是一个字符常量,其值是对应的ASCII值,

由于ASCII表中0的值是48,1的值是49,而此处c只有可能是49或48,即当前的c若是1,则n的二进制形式在左移一位的同时,右边补上一个1,若是0,同理,补上一个0。与循环和移位配合,最终达到n的二进制形式与我们输入的二进制数相等的目的。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值