查看: 1593|回复: 0
打印 上一主题 下一主题

移位运算的右移。

[复制链接]
跳转到指定楼层
沙发
发表于 2015-9-24 08:13:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
移位运算的右移。
     右移的运算符号是“>>”,语法格式如下:
     保存变量=被移数>>n;
        其中n代表“被移数”需要右移的位数。
     整句语法的含义是:“被移数”的二进制格式数据被整体往右边移动了n位,原来低n位数据被直接覆盖,新空出的高n位数据填入0。最后把移位结果存入“保存变量”。
     现在举一个完整的例子来分析“右移”运算的规律。有2个unsigned char类型的变量a和b,a的初始值是十进制数5,a=a>>1的结果是多少?b的初始值也是十进制数5,b=b>>2的结果是多少?
分析步骤如下:
     第一步:先把参与运算的数转换成二进制的格式。十进制转二进制的方法请参考前面第13,14,15节的内容。
十进制5的二进制格式是:00000101。
     第二步:
(1)将5的二进制数整体往右边移动1位:
                     原来是:00000101
        整体往右移动1位后变成:00000010
        把二进制的00000010转换成十六进制是:0x02。转换成十进制是2。所以a初始值是5, 右移1位后的结果是2.
(2)将5的二进制数整体往右边移动2位:
                    原来是:00000101
        整体往右移动2位后变成:00000001
        把二进制的00000001转换成十六进制是:0x01。转换成十进制是1。所以b初始值是5, 右移2位后的结果是1。
     上一节讲的“左移”1位有乘以2的规律,相反,这节讲的“右移”也存在整除的规律:某数右移1位相当于此数整除2,右移多少位相当于整除多少个2.比如上述例子中5右移1位相当于5整除2,结果等于2。而5右移2位相当于5整除2再整除2,5/2/2的结果等于1。既然右移1位相当于某个数整除2,那么为什么不直接用整除来替代右移呢?原因是一条右移语句的运算速度比一条整除语句的运算速度要快很多倍。
     右移是在单片机项目中很常用的语法,也经常应用在一些数据类型之间的拆分中。比如有一个双字节unsigned int类型的变量c,它的初始值是0x1234,要把它拆分成两个unsigned char单字节的类型数据H和L,其中H是高8位字节,L是低八位字节,拆分后H应该等于0x12,L应该等于0x34,此程序如何写?就需要用到右移。程序分析如下:
unsigned char H;  //单字节
unsigned char L;  //单字节
unsigned int c=0x1234; //双字节
L=c;  //c的低8位直接赋值给单字节的L
H=c>>8;  //c先把高8位右移到低8位,然后再把这8位数据赋值给H
        程序运行结果:H就等于十六进制的0x12,十进制是18。L就等于十六进制的0x34,十进制是52.提一个问题,请问执行完上述最后一条语句H=c>>8后,此时c的值是多少?答案是0x1234,因为只要它没有赋值给它自己,执行完语句后就不会改变它自己本身。
     再多讲一下知识点,右移也存在简写格式,比如:
e>>=1; //就相当于e=e>>1;
f>>=2; //就相当于f=f>>2;
        现在编写一个程序来练习刚才讲到的主要内容,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:

void main() //主程序
{
/*---C语言学习区域的开始---------------------------------------------------------------------------*/

  unsigned char a=5;
  unsigned char b=5;


  unsigned char H;  //单字节
  unsigned char L;  //单字节
  unsigned int c=0x1234; //双字节

  unsigned int d;

  a=a>>1;
  b=b>>2;

  L=c;  //c的低8位直接赋值给单字节的L
  H=c>>8;  //c先把高8位右移到低8位,然后再把这8位数据赋值给H

  //执行上述语句后,此时的c变量的数值是多少呢?
  //答案是0x1234,因为只要没有赋值给它自己,就不会改变它自己.

  d=c;  //此时d就等于c,是十六进制的0x1234.十进制是4660

  GuiWdData0=a;   //把a这个变量放到窗口变量0里面显示
  GuiWdData1=b;   //把b这个变量放到窗口变量1里面显示
  GuiWdData2=H;   //把H这个变量放到窗口变量2里面显示
  GuiWdData3=L;   //把L这个变量放到窗口变量3里面显示
  GuiWdData4=d;   //把d这个变量放到窗口变量4里面显示

/*---C语言学习区域的结束---------------------------------------------------------------------------*/
   while(1)  
   {
      initial();
      key_service();
      display_service();
   }

}
复制代码

        查看运算结果的方法。如何在坚鸿51学习板上观察变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。按下S9按键不松手就可以切换到十六进制的显示界面,松开手后会自动切换到十进制的界面。16个LED灯显示的就是当前变量的二进制数,亮代表1,灭代表0。上坚鸿51学习板观察程序执行的结果如下:
     变量a为2 (十六进制是0x02,二进制是00000010)。
     变量b为1(十六进制是0x01,二进制是00000001)。
     变量H为18(十六进制是0x12,二进制是00010010)。
     变量L为52(十六进制是0x34,二进制是00110100)。
     变量d为4660(十六进制是0x1234,二进制是0001 0010 0011 0100)。

     下节预告:括号改变优先级。
(未完待续)转载

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表