c++ bitset怎么用?c++如何高效进行位运算

来源:Golang编程网作者:新井头衔:网络博主
导读:本期聚焦于小伙伴创作的《c++ bitset怎么用?c++如何高效进行位运算》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《c++ bitset怎么用?c++如何高效进行位运算》有用,将其分享出去将是对创作者最好的鼓励。

在c++程序开发中,位运算是优化性能、简化逻辑的重要技巧,尤其是在处理状态标记、权限控制、数据压缩等场景时,直接操作二进制位能大幅减少内存占用和计算开销。c++标准库提供的bitset容器封装了完整的位操作能力,既保留了位运算的高效性,又避免了手动操作位运算符可能出现的逻辑错误,是处理固定长度位序列的常用工具。

c++ bitset怎么用?c++如何高效进行位运算

bitset基础概念与初始化

bitset是c++ STL中的模板类,位于<bitset>头文件中,它的模板参数指定了位序列的长度,这个长度在编译期就必须确定,因此bitset适合处理长度固定的位操作场景。

常见的初始化方式有以下几种:

  • 默认初始化:所有位都设为0
  • 用整数初始化:将整数的二进制表示存入bitset
  • 用字符串初始化:字符串中的0和1对应bitset的位

下面是初始化示例:

#include <bitset>
#include <iostream>
#include <string>

int main() {
    // 默认初始化,长度为8,所有位为0
    std::bitset<8> bs1;
    // 用整数初始化,整数5的二进制是00000101
    std::bitset<8> bs2(5);
    // 用字符串初始化,字符串从左到右对应高位到低位
    std::bitset<8> bs3("10110001");
    
    std::cout << "bs1: " << bs1 << std::endl;
    std::cout << "bs2: " << bs2 << std::endl;
    std::cout << "bs3: " << bs3 << std::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
reset(pos)将pos位置的位设为0
flip(pos)翻转pos位置的位,0变1,1变0
to_ulong()将bitset转换为unsigned long整数
to_string()将bitset转换为字符串

下面是成员函数的使用示例:

#include <bitset>
#include <iostream>

int main() {
    std::bitset<8> bs("10110001");
    
    std::cout << "位长度: " << bs.size() << std::endl;
    std::cout << "值为1的位数量: " << bs.count() << std::endl;
    std::cout << "是否存在值为1的位: " << bs.any() << std::endl;
    std::cout << "是否所有位都为0: " << bs.none() << std::endl;
    std::cout << "第3位是否为1: " << bs.test(3) << std::endl; // 位从0开始计数,右起第一位为0位
    
    bs.set(2); // 将第2位设为1
    std::cout << "set后: " << bs << std::endl;
    
    bs.reset(0); // 将第0位设为0
    std::cout << "reset后: " << bs << std::endl;
    
    bs.flip(7); // 翻转第7位
    std::cout << "flip后: " << bs << std::endl;
    
    std::cout << "转换为整数: " << bs.to_ulong() << std::endl;
    std::cout << "转换为字符串: " << bs.to_string() << std::endl;
    return 0;
}

bitset结合位运算符实现高效运算

bitset支持所有常用的位运算符,包括按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移(<<)、右移(>>),这些运算符可以直接作用于两个相同长度的bitset对象,运算效率非常高。

下面是位运算符结合bitset的使用示例:

#include <bitset>
#include <iostream>

int main() {
    std::bitset<8> bs1("10110001");
    std::bitset<8> bs2("01001010");
    
    // 按位与运算
    std::bitset<8> and_result = bs1 & bs2;
    std::cout << "按位与结果: " << and_result << std::endl;
    
    // 按位或运算
    std::bitset<8> or_result = bs1 | bs2;
    std::cout << "按位或结果: " << or_result << std::endl;
    
    // 按位异或运算
    std::bitset<8> xor_result = bs1 ^ bs2;
    std::cout << "按位异或结果: " << xor_result << std::endl;
    
    // 按位取反运算
    std::bitset<8> not_result = ~bs1;
    std::cout << "按位取反结果: " << not_result << std::endl;
    
    // 左移运算
    std::bitset<8> left_shift = bs1 << 2;
    std::cout << "左移2位结果: " << left_shift << std::endl;
    
    // 右移运算
    std::bitset<8> right_shift = bs1 >> 3;
    std::cout << "右移3位结果: " << right_shift << std::endl;
    return 0;
}

bitset与原生位运算的适用场景对比

虽然bitset封装了位操作,但原生位运算(直接对整数进行位操作)仍然有适用场景,两者的选择可以参考以下原则:

  • 如果位序列长度固定,且需要频繁进行位的状态查询、修改、统计,优先选择bitset,代码更简洁,可读性更高
  • 如果位序列长度不固定,或者需要处理的位长度超过bitset的最大支持长度(通常和unsigned long的长度相关),可以使用vector<bool>或者手动用整数数组模拟位运算
  • 如果是对单个整数进行简单的位操作,比如判断某个标志位是否置位,原生位运算的效率更高,不需要额外的容器开销

实战示例:用bitset实现权限判断

权限判断是位运算的典型应用场景,每个权限对应一个二进制位,1表示拥有该权限,0表示没有。下面用bitset实现一个简单的权限判断逻辑:

#include <bitset>
#include <iostream>
#include <string>

// 定义权限对应的位位置
const int READ_PERMISSION = 0;   // 读权限
const int WRITE_PERMISSION = 1;  // 写权限
const int EXECUTE_PERMISSION = 2;// 执行权限

int main() {
    // 用户权限bitset,初始拥有读和执行权限
    std::bitset<3> user_permission;
    user_permission.set(READ_PERMISSION);
    user_permission.set(EXECUTE_PERMISSION);
    
    // 判断是否有写权限
    if (user_permission.test(WRITE_PERMISSION)) {
        std::cout << "用户拥有写权限" << std::endl;
    } else {
        std::cout << "用户没有写权限" << std::endl;
    }
    
    // 新增写权限
    user_permission.set(WRITE_PERMISSION);
    std::cout << "新增写权限后,用户权限: " << user_permission << std::endl;
    
    // 移除执行权限
    user_permission.reset(EXECUTE_PERMISSION);
    std::cout << "移除执行权限后,用户权限: " << user_permission << std::endl;
    return 0;
}

通过上面的示例可以看出,bitset让权限判断的逻辑非常清晰,不需要手动计算位移和掩码,大大降低了出错概率。

注意事项

  • bitset的长度参数是编译期常量,不能在运行时动态修改,如果需要动态长度的位序列,可以考虑vector<bool>,但vector<bool>的性能和接口不如bitset友好
  • 访问bitset的位时,下标从0开始,0对应最低位(最右边的位)
  • 用字符串初始化bitset时,字符串的长度不能超过bitset的长度,否则会截断或者报错
  • to_ulong()转换时,如果bitset的值超过unsigned long的表示范围,会抛出std::overflow_error异常,使用时需要注意

bitsetc++位运算位操作STL容器修改时间:2026-07-05 10:18:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。