位运算符分析
C语言中位运算符直接对bit位进行操作,其效率最高。
注意点:
- 左操作数必须为整数类型
- char和short被隐式转换为int后进行移位操作
- 右操作数的范围必须为:[0-31]
- 左移运算符 << 将运算数的二进制左移
- 规则:高位丢弃,低位补0
- 右移运算符 >> 把运算数的二进制位右移
- 规则:高位补符号位,低位丢弃
一个有趣的问题
0x1 << 2 + 3 的值会是什么?
例子1:位操作符的使用
#include<stdio.h>
int main()
{
printf("%d
",3<<2); // 12
printf("%d
",3>>2); // 0
printf("%d
",0x1 << 2 +3); // 32
printf("%d
",-1>>1); // -1
printf("%d
",3 << -1); // 不同的编译器结果不一样,gcc 1
return 0;
}
防错准则:
- 避免位运算符、逻辑运算符和数学运算符同时出现在一个表达式中
- 当位运算符,逻辑运算符和数学运算符需要同时参与运算时,尽量使用括号来表达计算顺序
小tip:
- 左移n位相当于乘以2的n次方,但效率比数学运算高
- 右移n位相当于除以2的n次方,但效率比数学运算高
交换两个变量的值
#include<stdio.h>
#define SWAP(a,b)
{
int temp = a;
a = b;
b = temp;
}
#define SWAP1(a,b)
{
a = a + b;
b = a - b;
a = a - b;
}
#define SWAP2(a,b)
{
a = a^b;
b = a^b;
a = a^b;
}
int main()
{
int a = 200,b = 300;
printf("a = %d,b = %d
",a,b);
SWAP(a,b);
printf("a = %d,b = %d
",a,b);
SWAP1(a,b);
printf("a = %d,b = %d
",a,b);
SWAP2(a,b);
printf("a = %d,b = %d
",a,b);
return 0;
}
第一种方式引入了第三个变量,第二种,当两个大数相加可能产生溢出,第三种较好。
小结
- 位运算符只能用于整数类型
- 左移和右移运算符的右操作数的范围在[0,31]
- 位操作符没有短路规则,所有操作数都会求值
- 位运算符的效率高于四则运算和逻辑运算
- 运算优先级:四则运算 > 位运算 > 逻辑运算