位操作与位操作符
时间:2023-09-01 11:37:00
// ///无论什么进制数,其值都是每个数字和位权乘积之和 ///进制对应关系:二进制转换为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 #include 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 #include 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 #include 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,则报告有障碍