C语言中的位运算符
位运算符直接对 bit 位进行操作,其效率最高
左移和右移注意点
- 左操作数必需为整数类型
- 右操作数的范围必需为:【0,31】
- 左移运算符 << 将运算符的二进制位左移动
- 右移运算符 >> 把运算符的二进制位右移动
- char 和short 被隐士转换为 int 后进行移位操作
- 如果出现负数(-1)的情况编译厂家不同,结果不同
- 规则:高位丢弃,低位补0
- 规则:高位补符号位,低位丢弃
问题:
下面的运算结果是什么?
0x1 << 2 + 3
实验:
#include <stdio.h>
int main()
{
printf("%d\n", 3 << 2);
printf("%d\n", 3 >> 1);
printf("%d\n", -1 >> 1);
printf("%d\n", 0x01 << 2 + 3);
printf("%d\n", 3 << -1); // oops!
return 0;
}
输出
12
1
-1
32
1 // GCC编译器下认为左移-1 相当于右移1
运算优先级:四则运算>位运算>逻辑运算
移位为负数的情况下和不同编译器情况是不一样的(依赖编译器)
编程试验:交换两个整型变量的值
#define Swap1(a, b) \
{ \
int c = a; \
a = b; \
b = c; \
}
// 这个问题 a b 数据过大,会导致数据溢出
#define Swap2(a, b) \
{ \
a = a + b; \
b = a - b; \
a = a - b; \
}
#define Swap3(a, b) \
{ \
a = a ^ b; \
b = a ^ b; \
a = a ^ b; \
}
位运算与逻辑运算不同
- 位运算没有短路原则,每个操作都参与运算
- 位运算的结果为整数,而不是0和1
- 位运算优先级高于逻辑运算
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
int k = 0;
// if( ++i || ++j && ++k )
if( ++i | ++j & ++k )
{
printf("Run here...\n");
}
printf("%d\n", i);
printf("%d\n", j);
printf("%d\n", k);
return 0;
}
输出:
//Run here...
//1
//0
//0
Run here...
1
1
1
小结
- 位运算只能用于整数类型
- 左移或者右移的操作数范围必需是【0:32】
- 位运算没有短路原则,所有操作数均会求值
- 运算优先级:四则运算 > 位运算 > 逻辑运算