学过单片机的人肯定知道,既可以用汇编语言编写单片机程序也可以用C语言来编单片机写程序,其实C语言能支持汇编语言的大部分运算,因此C语言也支持汇编中的按位运算,可以说C语言既有高级语言的特点,又有低级语言的功能,正因为此使得C语言运用很广泛。
一、位运算操作符:
前面已经提到过一些关于位操作符的简要说明,分别有:按位与操作符(&)、按位或(|)、位取反(~)、按位异或(^)、左移(<<)以及右移(>>),下面对每个作简要说明:
①、按位与(&):此运算符是双目运算符,功能是把参与运算的两数对应的二进制位进行与操作,只有对应的位都为1时才返回1,其余返回0,如38&81=?,首先把他们转换为二进制数,38二进制形式为00100110,81二进制形式为01010001,然后进行按位与操作:00100110&01010001=00000000(十进制数0),因此得到38&80=0。
其实按位与的其中一个用途就是清零,当然还有保留指定位,如98要保留后四位,则可以与上00001111,又如要保留98的1、3、5、7位,那么可以与上01010101,对应位为1即可。
还有一个作用就是,取一个数中某些特定位,如要取98的后四位,那么可以与上00001111,上面只是为了简单取一个字节(8位)的长度,运用到实际中主要看类型的长度,比如32位机器中基本整型占4个字节(32位)。
②、按位或(|):
按位或(|)运算符是双目运算符,功能是把参与运算的两数对应的二进制位进行或操作,其中只要有一个位为1,结果就返回1,如38|81,也要转换为二进制数,即可得00100110|01010001=01110111(十进制数119)。
用途:通常用来将某一数据的特定位指定为1,如要将81的后五位置1,只需与31(00011111)进行按位或运算即可。
③、取反(~):
此运算符为单目运算符,具有右结合性,取反很好理解,也就是将一个数据的每个二进制位进行取反操作,1变为0,0变为1,如~38=~00100110=11011001。
④、异或运算符(∧):
异或运算符是双目运算符,功能是将参与运算的两数对应的二进制位进行异或操作,异或操作只有两二进制数对应的二进制位相异时才返回1,1∧1跟0∧0返回0,只有1∧0才返回1。如38∧255,00100110∧1111 1111=11011001。
用途1:上面有一个明显的特征,那就是00100110(38)跟结果11011001,对应二进制位都相反,这也就是异或运算符其中的一个作用,那就是翻转功能,把一个数据进行翻转,当然也可以指定翻转哪些位,比如上面的把38的后四位进行翻转,那么只需与一个后四位都是1的数进行异或操作。
用途2:这一用途不错,那就是如果需要交换两变量的值,完全可以不需要借助临时变量来实现两变量值互换,如char a=38,b=98,交换两变量的值一般方法:char c,c=a,a=b,b=a。异或方法:a=a∧b(0010 0110∧0110 0010=0100 0100(68)),b=a∧b(0100 0100∧0110 0010=0010 0110(38)),a=a∧b(0100 0100∧0010 0110=0110 0010(98)),从而实现了交换。
用途3:可以简单的加密,如x=98,与38异或加密,可得0110 0010∧0010 0110=0100 0100(68),只需要知道密码为38,那么就可以使用38异或还原原值,68∧38=98。当然你也可以使用其他数也可。
⑤、左移运算符(<<):
左移运算符是双目远算符,如a<<n,右边的操作数n是a的二进制位需要向左移动的位数,高位丢弃,右边补0,如38<<2,38二进制为0010 0110向左移动两位,1001 1000。左移一位相当于乘以2,但是仅限于移出为不包含1的情况。
⑥、右移运算符(>>):
右移当然也是双目运算符,如a>>n,右边的操作数n是指a二进制位向右移动的位数。但是有一点要注意,那就是有符号数的右移,当为非负数时右移是左边补0,但当为负数时,左边空出的必须以1补齐,其实要是左边补0,就称为逻辑右移,补1就称为算术右移。如-38>>2,-38的二进制数为1101 1010右移两位,由于是负数,符号位为1,故右移两位后左边补1,得,11110110。
二、循环位移:
前面讲过左移跟右移,都是把溢出的位丢弃,用0或1来补充,但是循环位移不同,它把低位溢出的位补充到高位(高位溢出的位补充到低位)。
①、循环左移:
循环左移的实现:首先呢,有一变量int z,然后将x的高n位保存到z的低n位中,基本整型变量一般是32位(不同机器可能有所不同),怎么实现呢?要想把x的高n位保存到z的低n位中,那就先把x向右移动32-n位,然后直接赋给z就可以了,即z=x>>(32-n),而后将x左移n位,低位以0补齐,即y=x<<n,低位以0补齐,而后通过与z按或运算,y=y|z就可以得到循环左移n位的结果。至于循环右移只需将上面的左移跟右移符号颠倒一下就可以实现。