C语言中的位运算符
位运算符直接对bit位进行操作,其效率最高。(比四则运算高很多)
左移和右移注意点:
1)左操作数必须为整数类型;
char和short被隐式转换为int后进行移位操作。
2)右操作数的范围必须为:[0,31]
左移-1或者右移32结果不确定,因为标准C没规定其行为,编译器开发商定义。
3)左移运算符<<将运算数的二进制左移;
规则:高位丢弃,低位补0;
4)右移运算符>>把运算数的二进制位右移;
规则:高位,补符号位,低位丢弃;(高位补符号位)
右操作数为负数,如何操作?是否正确?取决于编译器。
0x1<< 2 + 3的值会是什么?
编程确认:
分析:B同学对了。左移-1和编译器有关,gcc实则右移1位。VS为0,BCC为整数最小值。
防错准则:
1)避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中;
2)当位运算符,逻辑运算符和数学运算符需要同时参与运算时,尽量使用括号()来表达计算次序。
小技巧:
- 左移n位相当于乘以2的n次方,但效率比数学运算符高;
2)右移n位相当于除以2的n次方,但效率比数学运算符高;
(嵌入式开发时,对效率要求高时)
程序分析:(交换两个整型变量的值)
方法1: 中间变量
方法2: a = a+b;(存在溢出问题)
b = a-b;
a = a-b;
方法3:异或方法
主要的原理是:
(1)一个变量按位异或自己的结果为0,即:a ^ a = 0;
(2)一个变量按位异或0的结果为自己,即:a ^ 0 = a;
于是,在上面的三条语句中,语句1可以看做把变量a、b保存到a的存储空间中(当然这只是一种理解方式);语句2消去了b(原理1),于是剩下了a(原理2),赋值到b的存储空间,此刻,b变量已经得到了a的值;语句3中,原本a变量存储空间内已经同时保存了a、b,此刻,b已经变成了a,所以两个按位异或后,便消去了a(原理1),只剩下了b(原理2),将它赋值给a,至此,交换变量的过程结束。
位运算符与逻辑运算不同:
1)位运算没有短路原则,每个操作数都参与运算;
2)位运算的结果为整数,而不是0或1;(逻辑运算只有真和假)
3)位运算优先级高于逻辑运算优先级;
小结:
1)位运算符只能用于整数类型;
2)左移和右移运算符的右操作数范围必须为[0,31];
3)位运算没有短路原则,所有操作数均会求值;
4)位运算的效率高于四则运算和逻辑运算;
5)运算优先级:四则运算>位运算>逻辑运算;