c++的bitset是标准库提供的位操作容器,它固定了存储的二进制位数量,内部通过高效的位运算实现各种操作,比手动用整数做位运算更直观也更安全,适合处理需要频繁操作二进制位的场景。

bitset的基本初始化方式
bitset的模板参数需要指定固定的位长度,初始化时可以传入整数、字符串或者默认初始化,以下是常见的初始化示例:
#include <bitset>
#include <iostream>
#include <string>
using namespace std;
int main() {
// 默认初始化,所有位都是0
bitset<8> b1;
// 用整数初始化,整数会转换为二进制存储
bitset<8> b2(13); // 13的二进制是00001101
// 用字符串初始化,字符串需要是0和1组成的序列
bitset<8> b3("10110011");
// 用字符串的部分区间初始化,从索引0到索引4的子串
string s = "11010101";
bitset<8> b4(s, 0, 5); // 取前5位11010,不足8位前面补0,结果为00011010
cout << "b1: " << b1 << endl;
cout << "b2: " << b2 << endl;
cout << "b3: " << b3 << endl;
cout << "b4: " << b4 << endl;
return 0;
}
bitset的常用成员函数
bitset提供了丰富的成员函数,覆盖位访问、位修改、位统计、位运算等需求,以下是高频使用的函数说明:
| 函数名 | 功能说明 |
|---|---|
| size() | 返回bitset的位长度 |
| count() | 返回bitset中值为1的位的数量 |
| any() | 判断是否有任意一位为1,有则返回true |
| none() | 判断是否所有位都为0,是则返回true |
| test(pos) | 判断pos位置的位是否为1,是则返回true |
| set(pos, val) | 将pos位置的位设置为val,val默认是1,不传pos则设置所有位为1 |
| reset(pos) | 将pos位置的位设置为0,不传pos则设置所有位为0 |
| flip(pos) | 翻转pos位置的位,0变1,1变0,不传pos则翻转所有位 |
| to_ulong() | 将bitset转换为unsigned long整数 |
| to_string() | 将bitset转换为0和1组成的字符串 |
bitset位操作实例
bitset支持位与、位或、异或、左移、右移等运算,以下是具体的操作示例:
#include <bitset>
#include <iostream>
using namespace std;
int main() {
bitset<8> b1("10101010");
bitset<8> b2("11001100");
// 位与运算
bitset<8> and_res = b1 & b2;
cout << "位与结果: " << and_res << endl; // 10001000
// 位或运算
bitset<8> or_res = b1 | b2;
cout << "位或结果: " << or_res << endl; // 11101110
// 异或运算
bitset<8> xor_res = b1 ^ b2;
cout << "异或结果: " << xor_res << endl; // 01100110
// 左移2位
bitset<8> left_shift = b1 << 2;
cout << "左移2位结果: " << left_shift << endl; // 10101000
// 右移3位
bitset<8> right_shift = b1 >> 3;
cout << "右移3位结果: " << right_shift << endl; // 00010101
return 0;
}
bitset实际应用场景示例
场景1:统计二进制中1的个数
用count()函数可以一行代码完成1的个数统计,比手动循环位运算更简洁:
#include <bitset>
#include <iostream>
using namespace std;
int main() {
int num = 29; // 二进制11101
bitset<32> b(num); // 用32位bitset存储
cout << num << "的二进制中1的个数是: " << b.count() << endl; // 输出4
return 0;
}
场景2:状态标记管理
可以用bitset的每一位表示一个独立的状态,适合管理多个布尔类型的状态:
#include <bitset>
#include <iostream>
using namespace std;
int main() {
// 用8位bitset表示8个任务的状态,1表示完成,0表示未完成
bitset<8> task_status;
// 任务1、3、5完成
task_status.set(0); // 第0位对应任务1
task_status.set(2); // 第2位对应任务3
task_status.set(4); // 第4位对应任务5
cout << "当前任务状态: " << task_status << endl;
cout << "完成的任务数量: " << task_status.count() << endl;
// 判断任务3是否完成
if (task_status.test(2)) {
cout << "任务3已完成" << endl;
}
// 重置任务1的状态为未完成
task_status.reset(0);
cout << "重置后任务状态: " << task_status << endl;
return 0;
}
使用bitset的注意事项
- bitset的位长度是模板参数,编译时就固定,无法动态修改大小,如果需要动态长度可以考虑vector<bool>,但bitset的性能和操作便捷性更好。
- 用字符串初始化bitset时,字符串只能包含0和1,否则会抛出异常,实际使用时建议先做合法性校验。
- bitset的位索引从右往左是从低位到高位吗?不是,索引0对应的是二进制的最右位(最低位),比如bitset<8>("00000001")的0位是1,对应数值1。
- to_ulong()转换时如果bitset的值超过unsigned long的范围,会抛出overflow_error异常,转换前可以先判断数值范围。