C语言强大的特点之一就是可以对构成计算机数据最小的不可分割的数据单位-----位 进行操作。操作类型主要有以下6种方式
操作 | 含义 |
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 取反 |
<< | 左移 |
>> | 右移 |
这些操作主要用于整形数据或字符型数据 下面分别说明各个操作的用法
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
&按位与
Bit1 | Bit2 | Bit1 & Bit2 |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
进行与操作的两个位,只有同时为1时结果才为1,有一个为0结果就为0;美国大片中经常有这样的一幕,要发射一个称为原子弹的东西,必须两个人同时插入钥匙,并扭动
按钮方可启动。还有我们生活中也有很多类似与的事情,
王家老五要结婚,有房吗?没有(0),有车吗?没有(0)-----》结不了(0)。
王家老五要结婚, 有房吗?有(1), 有车吗?没有(0)-------》结不了(0)。
王家老五要结婚, 有房吗?没有(0), 有车吗?有(1)-------》结不了(0)。
王家老五要结婚, 有房吗?有(1), 有车吗?有(1) -------》入洞房(1)。
学文科的常说“艺术源于生活,却高于生活”。我们搞IT的也可以说“技术源于生活,用于生活^^”
根据与操作的特性,在计算机编程中与操作的主要有两个用途
1)设置指定位为0 例如某数:01101001 我想把最左边的1设置为0
01101001 | |
& | 10111111 |
00101001 |
0与任何数都为0
2)取出指定位的数 01101001 我想把从左数第5位取出来
01101001 | |
& | 00001000 |
00001000 |
这样通过结果就可以得知所与的数的第5位是1还是0 因为1与任何数,那个数不变
通常我们在实际开发中也经常用与的特性来判断一个数是奇数还是偶数,偶数转换为二进制后,最低位始终为0,而奇数始终为1
所以
int even(int value)
{
return ((value & 1) == 0);
}
传入的参数value与1如果是偶数则返回1,否则返回0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 按位或
Bit1 | Bit2 | Bit1 | Bit2 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
按位或只要进行或操作的数中有一个为1,结果就为1
我饿了,包子有没?没有(0), 面条有没?没有(0);继续饿(0)
我饿了,包子有没?没有(0), 面条有没?有(1); 吃饱了(1)
我饿了,包子有没?有(1), 面条有没?没有(0);吃饱了(1)
我饿了,包子有没?有(1), 面条有没?有(1); 吃饱了(1)
根据或操作的特性,在计算机编程中的主要用途
设置指定位为1, 还是01101001这个数我想把最高位的0置为1
01101001 | |
| | 10000000 |
11101001 |
因为1或上任何数都为1,而0或上任何数,那个数不变
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
^ 按位异或
Bit1 | Bit2 | Bit1 ^ Bit2 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
按位异或,相异的两个数相同结果则为0, 不同则为1
按位异或通常有以下几种用途
1)使某些特定的位取反
例如使01101001从左数第3位和第4位取反
01101001 | |
^ | 00011000 |
01110001 |
只需要把需要置换的两个位与上1其它与上0就可以实现取反
0与任何数异或那个数不变,1与任何数异或那个数就会取反
(1) 0^0=0,0^1=1 0异或任何数=任何数
(2) 1^0=1,1^1=0 1异或任何数-任何数取反
(3) 任何数异或自己=把自己置0
2)不用第三方变量交换两个数
假设a = 2, b = 3 那么
a = a ^ b;
a | 10 |
^b | 11 |
a= | 1 |
b = a ^ b;
a | 1 |
^b | 11 |
b= | 10 |
a = a ^ b;
a | 1 |
^b | 10 |
a= | 11 |
最张实现两个数的交换。而位操作通常比加减法运算快得多
3) 将某变量快速置0
int a = a ^ a;
自然也可以根据这个特性判断两个数是否相等
return ((a ^ b) == 0);
相等返回1,否则返回0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
~按位非
Bit | ~Bit |
1 | 0 |
0 | 1 |
按位非就是1变0, 0变1, ~是一个单目操作符
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<< 左移操作 >>右移操作
对于变量x , x << n 所得结果为x乘2的n次方, x>>n结果相当于x除以2的n次方int x = 9;
x = x << 2;// x = 36
x = 9;
x = x >> 2;// x = 2
1001<<2 | = 100100 |
1001>>2 | = 10 |
能够执行移位操作的数据类型
char、short、int、long、unsigned char、unsigned short、unsigned int、unsigned long都可以进行移位操作,而double、float、bool、long double则不可以进行移位操作。
有符号数据类型的移位操作
对负数进行左移:符号位始终为1,其它位左移
对正数进行左移:所有位左移,可能会变成负数
对负数进行右移:取绝对值,然后右移,再取反
对正数进行右移:所有位右移
无符号数据类型的换位操作
对于unsigned char、unsigned short、unsigned int、unsigned long这些无符号数据类型:
移位就行了,没有特殊说明