在C++中位操作进行条件判断(开关设置)
工作中用的,整理一下
#include <iostream>
#include <cstdint>#define MOUSE (1 << 1)
#define PANNEL (1 << 2)void Updage(uint32_t &ret, int num) {std::cout << "\nSTART" << std::endl;if ((ret & MOUSE) != 0 && num > 5) {ret &= ~MOUSE;std::cout << "MOUSE " << MOUSE << std::endl;}if ((ret & PANNEL) != 0 && num > 5) {ret &= ~PANNEL;std::cout << "PANNEL " << PANNEL << std::endl;}
}void Excute() {uint32_t ret = 0xFFFF; // 所有开关都开启Updage(ret, 7);Updage(ret, 10);
}int main() {Excute();system("pause");return 0;
}
0xff 是一个常见的十六进制数,表示二进制的 1111 1111,即 8 位全为 1。它通常用于按位与操作,以保留一个数的低 8 位。
常见应用
取得低 8 位
在一些情况下,我们只需要一个数的低 8 位。例如,在网络通信中,数据长度信息可能需要分成高 8 位和低 8 位来处理:
int length = 0x1234;
int high8 = (length >> 8) & 0xff; // 取高 8 位
int low8 = length & 0xff; // 取低 8 位
在这个例子中,0x1234 的二进制表示为 0001 0010 0011 0100,而 0xff 的二进制表示为 1111 1111。按位与操作后,结果为 0000 0000 0011 0100,即 0x34。
保证补码一致性
在处理负数时,按位与 0xff 可以确保补码的一致性。例如:
byte b = -127; // 1000 0001
int a = b & 0xff; // 结果为 129
在这个例子中,-127 的补码为 1000 0001。将 byte 转换为 int 时,高 24 位会补 1,结果为 1111 1111 1111 1111 1111 1111 1000 0001。通过与 0xff 进行按位与操作,高 24 位被置为 0,结果为 0000 0000 0000 0000 0000 0000 1000 0001,即 129。
而上面例子中使用的 0xFFFF 是无符号32位整数,十六进制为 0xff。
(ret & PANNEL) != 0 可以换成 ret & PANNEL 因为 ret & PANNEL 可以转换为 bool 值
这个写得不太专业,再看网上写得专业的例子
#include <iostream>
using namespace std;class Switches {
public:unsigned int state = 0; // 默认为 0,所有开关都关闭void set(int position, bool value) {if (value) {state |= (1 << position); // 开启开关} else {state &= ~(1 << position); // 关闭开关}}bool get(int position) const {return (state & (1 << position)) != 0; // 检查开关状态}void toggle(int position) {state ^= (1 << position); // 切换开关}
};int main() {Switches switches;cout << "Initial get: " << endl;cout << (switches.get(0) ? "F1 ON " : "F1 OFF ") << endl; // 检查F1开关状态cout << (switches.get(1) ? "F2 ON " : "F2 OFF ") << endl; // 检查F2开关状态cout << (switches.get(2) ? "F3 ON " : "F3 OFF ") << endl; // 检查F3开关状态cout << endl;// 开启F1和F2,关闭F3(实际上这里关闭操作是多余的,因为初始化为0)switches.set(0, true); // 开启F1开关switches.set(1, true); // 开启F2开关switches.set(2, false); // 开启F3开关cout << "After get: " << endl;cout << (switches.get(0) ? "F1 ON " : "F1 OFF ") << endl; // 检查F1开关状态cout << (switches.get(1) ? "F2 ON " : "F2 OFF ") << endl; // 检查F2开关状态cout << (switches.get(2) ? "F3 ON " : "F3 OFF ") << endl; // 检查F3开关状态cout << endl;// 切换开关状态switches.toggle(1); // 切换F2开关状态switches.toggle(2); // 切换F3开关状态cout << "After toggling F2: " << endl;cout << (switches.get(0) ? "F1 ON " : "F1 OFF ") << endl; // 检查F1开关状态cout << (switches.get(1) ? "F2 ON " : "F2 OFF ") << endl; // 检查F2开关状态cout << (switches.get(2) ? "F3 ON " : "F3 OFF ") << endl; // 检查F3开关状态system("pause");return 0;
}
将 state 初始值改为 0xff,则变成开关初始值全部为开启状态。