Summary
1)C语言中的位运算符:
运算符 | 意义 | 规则 |
---|---|---|
& | 按位与 | 全1得1,有0得0 |
I | 按位或 | 有1得1,全0得0 |
^ | 按位异或 | 相同为0,不同得1 |
~ | 取反 | 1变0, 0变1 |
<< | 左移 | 高位丢弃,低位补0 |
·>> | 右移 | 高位补符号位,低位舍弃 |
2)左移、右移的注意点:
左操作数必须是整数类型
- char和short被
隐式转换
为int后进行操作
- char和short被
右操作数的范围必须为:[0,31]
,否则结果未定义
(不同编译器处理结果不同)左移运算符<<
将运算数的二进制位左移,效果相当于乘以2的n次方
,效率
更高右移运算符>>
将运算数的二进制位右移,效果相当于除以2的n次方
,效率
更高- 避免位运算符、逻辑运算符、数学运算符等混合运算,如果必须这样,使用括号表示好计算顺序。(
单算移比、按逻三赋
)
3)位运算注意点:
- 位运算没有短路规则,
每个操作数都会参与运算
- 位运算的
结果是整数
,而不是0或1 - 位运算的优先级高于逻辑运算(
单算移比 按逻三赋
)
4)交换两个整形变量的值:
Demo1:
部分和
方式:不使用中间变量,但存在溢出的问题#define SWAP(a, b) \ { \ a = a + b; \ b = a - b; \ a = a - b; \ }
Demo2:
位运算
方式:使用异或(两个相同的值异或结果为0,任何数和0异或仍为本身
)#define SWAP(a, b) \ { \ a = a ^ b; \ b = a ^ b; \ a = a ^ b; \ }
位运算符剖析
C语言最初设计用来开发UNIX操作系统,操作系统运行于硬件平台之上,必然会涉及位运算,需要对硬件的bit位(0和1)进行操作。C语言中位运算直接映射到了硬件系统中的位运算。
位运算符直接对bit位进行操作
,其效率最高
。
1、C语言中的位运算符
运算符 | 意义 | 规则 |
---|---|---|
& | 按位与 | 全1得1,有0得0 |
I | 按位或 | 有1得1,全0得0 |
^ | 按位异或 | 相同为0,不同得1 |
~ | 取反 | 1变0, 0变1 |
<< | 左移 | 高位丢弃,低位补0 |
·>> | 右移 | 高位补符号位,低位舍弃 |
2、左移和右移的注意点
左操作数必须是整数类型
- char和short被
隐式转换
为int后进行操作
- char和short被
右操作数的范围必须为:[0,31]
,否则结果未定义
(不同编译器处理结果不同)左移运算符<<
将运算数的二进制位左移,效果相当于乘以2的n次方
,效率
更高右移运算符>>
将运算数的二进制位右移,效果相当于除以2的n次方
,效率更高- Demo1
d << 2; // error, 左操作数必须是整型 int x = 10 >> 1; // ok,"右移等效除以2的n次方",输出5 int y = -1 << 1; // ok,"左移等效乘以2的n次方",输出-2 int z = 3 << -1; // -1不在[0,31]范围中,结果未定义,不同编译器不同处理 // 编译器亦提示了错误:Possible overflow in shift operation // gcc 1, 左移-1相当于右移1,那就除以2,得到了1 // bcc -2147483648, int的最小值 // vc 0, 本来就未定义,给你0把
避免位运算符、逻辑运算符、数学运算符等混合运算,如果必须这样,使用括号表示好计算顺序。(
单算移比、按逻三赋
)- Demo2
0x1 << 2 + 3 输出多少? 等价于 0x1 << (2 + 3),输出为32 // 如果这行代码作者本意是先左移,再加法,实际执行结果就不是期望的 // 所以在写代码时要尽量用括号()来表示清楚计算次序
3、位运算注意点
- 位运算没有短路规则,
每个操作数都会参与运算
- 位运算的
结果是整数
,而不是0或1 位运算的优先级高于逻辑运算(
单算移比 按逻三赋
)int i = 0; int j = 0; int k = 0; if(++i | ++j & ++k) // 所有的运算数都会执行到,因此i j k判断后都为1 printf("cc");
4、 位运算应用简单示例
交换两个整形变量的值
Demo1:
部分和
方式:不使用中间变量,但存在溢出的问题#define SWAP(a, b) \ { \ a = a + b; \ b = a - b; \ a = a - b; \ }
Demo2:
位运算
方式:使用异或(两个相同的值异或结果为0,任何数和0异或仍为本身
)#define SWAP(a, b) \ { \ a = a ^ b; \ b = a ^ b; \ a = a ^ b; \ }
本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。