//位操作与位操作符
//无论什么进制的数,其值都是每位数字与位权乘积之和
//进制对应关系:二进制转换为16进制——逢四进一,不足前面补0,八进制为逢三进一
//C\C++语言中位操作符都用于整形对象,包括char、short、int、long、long long
// 且实际因涉及到补码对有符号整数操作较少
hex dec bin
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110
7 7 0111
8 8 1000
9 9 1001
a 10 1010
b 11 1011
c 12 1100
d 13 1101
e 14 1110
f 15 1111
#include <iostream>
#include <bitset>
using namespace std;
int main() {
//二进制字面量在C++14后引入,此前的版本用16进制代替,即0x5d
//C++标准库中bitset类型将对象转换位指定位数的二进制字符串
//C语言的printf()函数不支持把对象按二进制输出
//尖括号中8为模板参数,即将c转换为8位二进制字符串
//1.按位取反
//对每个二进制位,1变0,0变1
unsigned char c = 0b01011101;
unsigned char d = ~c;
cout << "c = " << bitset<8>(c) << endl;
cout << "~c = " << bitset<8>(d) << endl;
//用途
//(1)将每一位都取反
//(2)使一个数最低位为0,表示为a&~1
//2.按位与
//对每个二进制位进行与运算,对应二进制位均为1时结果为1,否则为0
unsigned int a = 0x8fff37a;
unsigned int b = 0xfc7779f6;
unsigned int e = a & b;
cout << "a = " << bitset<32>(a) << endl; //8位16进制数即8*4=32位2进制数
cout << "b = " << bitset<32>(b) << endl;
cout << "a & b = " << bitset<32>(e) << endl;
cout << "a = " << bitset<32>(a) << endl;
cout << "0xfffffff7 = " << bitset<32>(0xfffffff7) << endl;
a &= 0xfffffff7; //组合操作符 等价于a = a & 0xfffffff7
cout << "a & 0xfffffff7 = " << bitset<32>(a) << endl;
//0xfffffff7二进制下只有第3位为0,按位与操作后可使对象第3位为0
//按位与操作可将对象特定位“置0”,同时保持其他位不变
//用途
//(1)清零:要将一个单元清零,即使其全部二进制位为0,只要与一个各位为0的数值相 与,结果清零
//(2)取一个数的指定位:利用与运算将特定位之外的其他位全部“置0”
//3.按位或
//对每个二进制位进行或运算,对应二进制位至少有一个为1时结果为1,否则为0
unsigned short f = 0xf37a;
unsigned short g = 0x79f6;
unsigned short h = f | g;
cout << "f = " << bitset<16>(f) << endl; //4*4=16
cout << "g = " << bitset<16>(g) << endl;
cout << "f | g = " << bitset<16>(h) << endl;
cout << "f = " << bitset<16>(f) << endl;
cout << "0x0800 = " << bitset<16>(0x0800) << endl;
f |= 0x0800; //组合操作符
cout << "f | 0x0800 = " << bitset<16>(f) << endl;
//0x0800二进制下只有第11位为0,按位或操作后可使第11位为1
//按位或操作可将对象特定位“置1”,同时保持其他位不变
//用途
//对一个数的特定位“置1”
//4.按位异或
//当对应二进制位不同时结果为1,否则为0
unsigned char i = 0xb4;
unsigned char j = 0x77;
unsigned char k = i ^ j;
cout << "i = " << bitset<8>(i) << endl;
cout << "j = " << bitset<8>(j) << endl;
cout << "i ^ j = " << bitset<8>(k) << endl;
cout << "i = " << bitset<8>(i) << endl;
cout << "0xf0 = " << bitset<8>(0xf0) << endl;
i ^= 0xf0;
cout << "i ^ 0xf0 = " << bitset<8>(i) << endl;
//0xf0二进制下11110000,高4位将i的高4位取反,低4位同i的低4位
//按位异或可将该数要取反的对应位设1,其余位设0
//用途
//使特定位取反
//5.左移位
//对10进制数左移2位并右方补0,相当于把该数乘上10^2
//同理,不溢出的情况下,二进制数左移n位右方补0相当于把该数乘2^n
unsigned short m = 5;
cout << "m = " << bitset<16>(m) << ",value = " << m << endl;
m = m << 3;
cout << "m <<= 3 =" << bitset<16>(m) << ",value = " << m << endl;
//6.右移位
//没有损失有效位(即右移没有1被丢弃),将无符号整数右移n位,相当于该数除2^n
//原数为无符号整数用0填充左侧空位,有符号整数正数左补0,负数左补1
unsigned short n = 2368;
cout << "n = " << bitset<16>(n) << ",value = " << n << endl;
n = n >> 5;
cout << "n >>= 5 = " << bitset<16>(n) << ",value = " << n << endl;
//7.不同长度的数据进行位运算,系统会将二者按右端对齐后再进行运算
}
//8.置位(set bit即将指定位“置1”)与复位(reset bit即将指定位“置0”)
#include <iostream>
#include <bitset>
using namespace std;
//将v对象的第bit位置位
template <typename T>
inline void setBit(T& v, int bit) {
v |= (0x01 << bit);
} //0x01 << bit构造一个第bit位为1,其他全0的unsigned short
//再把此临时对象与v做按位或运算从而将v的第bit位置位
//将v对象的第bit位复位
template <typename T>
inline void resetBit(T& v, int bit) {
v &= (~(0x01 << bit));
} //0x01 << bit再按位取反构造一个第bit位为0,其他全为1的unsigned short
//再把此临时对象与v做按位与运算从而将v的第bit位复位
int main() {
unsigned short v = 0xff00;
cout << "before v = " << bitset<16>(v) << endl;
setBit(v, 6);
setBit(v, 0);
setBit(v, 11);
resetBit(v, 15);
resetBit(v, 10);
cout << "after v = "<<bitset<16>(v) << endl;
return 0;
}
//9.示例:地铁门障碍检测电路
//D1发光二极管在门左侧发出红外光;光敏三极管D2在门右侧,受光照导通,电极信号S0与地面导通为低电平
//门口有障碍物挡住D1发射红外线,D2断开,S0电阻升高为高电平
//S0信号与CPU端口管脚相连,有障碍物S0高电平,CPU认为值为1;无障碍物S0为低电平,CPU认为值为0
//地铁车厢共8节车厢16扇车门,CPU连接了S0~S15共16个传感器信号,设计程序检测哪几扇门有障碍物
#include <iostream>
#include <bitset>
using namespace std;
void testDoorSensors(unsigned short s, bool r[]) {
for (int i = 0; i < 16; i++)
r[i] = s & (0x01 << i);
}
int main() {
unsigned short s = 0x4031; //测试值
bool blocked[16];
cout << "s = " << bitset<16>(s) << endl;
testDoorSensors(s, blocked);
for (int i = 0; i < 16; i++) {
if (blocked[i])
cout << "Door " << i << " is blocked." << endl;
}
return 0;
}
//1.testDoorSensor()用于检测形参变量s的每一个二进制位,将结果存入r[]数组
// 对应二进制位为1则存入true,反之存入false
//2.0x01左移i位形成,仅第i位为1其余全0的unsigned short
//3.s与该临时对象做按位与运算,结果对象每一位都0,整个与运算结果为0,即false;
// 结果对象第i位为1,整个结果非0,即true
//4.遍历传感器变量s检测的结果数组blocked,若发现元素值为true,则报告有障碍
位操作与位操作符
最新推荐文章于 2024-03-16 21:50:53 发布