1、按二进制位进行的运算。
&与 |或 ^异或 ~取反 << 左移 >> 右移
2、由于是按二进制位进行运算,所以运算的数字只能是整型或字符型,不能是实数(语法给定,如果确实需要也是可以的。)
3、使用方式(特殊用途、编程技巧):
- & 原理:x&0 = 0,所以用于对指定位清零,或者是取出某些位
eg:1011&1110 = 1010 最后一位清零, 1011&0011 = 0011 取出最后两位
- | 原理:x|1 = 1,所以用于对指定位赋1
eg:1001 | 0010 = 1011
- ^ 原理: 同0异1 ,0^1 = 1,1^1 = 0,1^0 = 1,0^0=0 与0异或保持不变,与1异或变反, 用于使特定位翻转,另外翻转两次等于原数据。可用于交换数据。
eg:1001 ^ 0110 = 1111 a=a^b;b = b^a; a = a^b; a^b = b^a ; a^b^b = a ; a^b ^a = b;
- << 左移1位等于乘以2,高位在进位寄存器
- >> 右移一位等于除以2余数舍弃,关于右移时高位补位的问题,一般是根据符号位的值来决定,如果是无符号数,则统一补0,当然在不同的计算机中,也可能存在不同的情况。(java中,分为>>算术又移和>>> 逻辑又移)
4、位运算可以提高程序的运行效率,之前我们存储数据都是以字节为单位,那么能不能以位为单位呢?
答案是可以的, 可见C语言对于内存真的是太小气了,能用一个位就不用一个字节….
当然,CPU和存储器寻址的话还是以字节为单位了,千万不要以为CPU可以按位寻址,所以这里的以位为单位保存数据的方法,是编译器通过移位操作的方式来提供给我们的。用效率换内存(节约内存的结果就是额外增加许多操作)。
使用位段结构体的方式来把一个双字分为多个变量来使用。
eg:struct packed_data
{
unsigned a:4;
unsigned b:12;
unsigned c:8;
unsigned d:8;
}
位段成员必须是unsigned 或int 类型,可以用unsigned:0;使下一个位段从下一个存储单元开始存放。
位段的概念了解即可,除了某些单片机,恐怕一般都用不上了。