C语言的位运算

位运算概念:位运算是直接对二进制数位进行操作的运算。
C语言的位运算是C语言区别于其他高级语言的一大特色,利用这一功能C语言可以实现一些底层操作,如对硬件编程或系统调用。
注意:进行位运算时,数据对象只能是整型数(int、short int、unsigned int、long int)或字符型数,不能是其他的一些数据类型,如单精度或双精度型。
C语言包含6种位运算符,如下图
在这里插入图片描述
其中只有按位取反运算符“~”是单目运算符,其他均为双目运算符。
优先级顺序:
按位取反运算符“~”的优先级高于算数运算符和关系运算符的优先级,是所有位运算符中优先级最高的。其次是左移“<<”和右移“>>”运算符,这两个运算符优先级高于关系运算符的优先级,但低于算数运算符的优先级,按位与“&”、按位或“|”和按位异或“^”都低于算数运算符和关系运算符的优先级。

按位与运算(&)

按位与运算的作用是:将参与运算的两个操作数按对应的二进制位分别进行“与”运算,只有对应的两个二进制位均为1时,结果位才为1,否则为0。参与运算的数以补码的形式出现。例如9&8其结果为
9: 0 0 0 0 1 0 0 1
8: 0 0 0 0 1 0 0 0
————————
8: 0 0 0 0 1 0 0 0
按位与运算通常用来对某些位清零或保留位。 例如,操作数a的值是1001 1010 0010 1011,要将此数的高8位清零,低8位保留。解决的方法就是和0000 0000 1111 1111进行运算。运算后结果为0000 0000 0010 1011,操作数的高8位全为0,低8位与原来相同。

按位或运算(|)

按位或的运算规则是:参与运算的两个数对应的二进制位相或。只要对应的二进制位有一个为1,结果位就为1。 参与数均以补码的形式出现。例如:
0 0 1 0 0 1 1 0
0 0 0 1 1 0 1 1
———————
0 0 1 1 1 1 1 1
根据“|”运算的特点,可用于将数据的某些位置1,这只要待置位上二进制数为1,其他位为0的操作数进行“|”运算即可。

按位取反运算(~)

按位取反运算又叫按位非运算,就是将操作数的每一位都取反(即1变0,0变1)。它是位运算符中唯一的一个单目运算符。例如:0101 0011取反后为1010 1100

按位异或运算(^)

按位异或运算的运算规则是:两个参与运算的操作数中对应的二进制位若相同,则结果位为0,若不同,则结果位为1。例如
0 0 1 0 1 1 0 1
0 1 1 0 0 1 1 0
———————
0 1 0 0 1 0 0 1
与0异或的结果还是本身,与1异或的结果相当于原数按位取反。利用这以特性可以实现某操作数的其中几位翻转,这只要与另一相应位为1其余位为0的操作数异或即可。
异或也可实现两个数的交换,例如:

#include <stdio.h>
void main()
{
    
    
	int a,b;
	a=56,b=37;
	a=a^b;
	b=b^a;
	a=a^b;
	printf("a=%d,b=%d\n",a,b); 
}

其输出结果为a=37,b=56。改操作没有使用中间变量实现了ab的交换,这也是异或的一种用法。

左移运算(<<)

左移运算的规则是:把“<<”左边运算数的各二进制位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。例如:
x : 0000 0101 (x=5)
y=x<<1 :0000 1010 (y=10)
z=x<<2 :0001 0100 (z=20)

可以看出左移一位相当于原数乘2,左移n位相当于原数乘2^n,n是要移动的位数。实际运算中左移运算要比乘法运算快的多,所有常用左移来代替乘法运算。
**注意:左移运算代替乘法运算时,若左移出的部分包含二进制数1,特性就不适用了。**例:
x : 0100 0110 (x=70)
y=x<<1 :1000 1100 (y=140)
z=x<<2 :0001 1000 (z=24)

右移运算(>>)

右移运算的功能是把“>>”左边的运算数的各二进制位全部向右移动若各位,由“>>”右边的数决定移动的位数。左端的填补分为两种情况:若该数为无符号数或正整数,则高位补0;若该数是负整数,则高位补0或补1由编译系统决定。例如
a : 0000 1011
b=a>>2 : 0000 0010

总结

位运算是C语言的一大特色,通过位运算可以实现一些底层操作。在单片机编程中也有很多时候会运用到C语言的位运算。要熟悉每一种位运算的规则以及其能实现的功能。
“&”运算:通常用来对某些位清零或保留位
“|”运算:可用于将数据的某些位置1
“^”运算:可以实现某操作数的其中几位翻转,也可用来实现两个数的交换
“<<”运算:可代替乘法使用,但要注意其条件

还需要区分的一点就是“&&”和“&”、“||”和“|”,不要将逻辑与和位与、逻辑或和位或弄混。注意“>>”运算时高位的补位方式。
若参与运算的数长度不同,这时可以将两个数按右端对其进行运算,高位补位方式为:若较短的数为正数或无符号数,则其高位补足0;若较短的数为负数,则高位补满1。

猜你喜欢

转载自blog.csdn.net/Tao_9/article/details/129961428