当前位置: 首页 > news >正文

C++ 11和20中的位域使用说明-2

std::bitset 是一个模板类,用于表示和操作固定大小的位序列。它非常适合处理标志、权限、二进制数据等场景

基础知识:

#include <iostream>
#include <bitset>
#include <string>// 模板参数 N 是位集的大小(编译时确定)
std::bitset<N> bitset_name;

示例 1:基本构造与初始化

#include <iostream>
#include <bitset>
#include <string>int main() {// 1. 默认构造:所有位为 0std::bitset<8> b1; // "00000000"std::cout << "b1: " << b1 << std::endl;// 2. 从整数构造 (值被转换为其二进制表示)std::bitset<8> b2(42); // 42 的二进制是 101010, 所以是 "00101010"std::cout << "b2 (from int 42): " << b2 << std::endl;// 3. 从字符串构造std::bitset<8> b3("1010"); // 不足8位,前面补0 -> "00001010"std::cout << "b3 (from string \"1010\"): " << b3 << std::endl;std::bitset<8> b4(std::string("11001100"));std::cout << "b4 (from std::string): " << b4 << std::endl;return 0;
}

输出:

b1: 00000000
b2 (from int 42): 00101010
b3 (from string "1010"): 00001010
b4 (from std::string): 11001100

示例 2:C++20 新增的构造函数 - std::from_chars

这是 C++20 的一个重要改进,允许从字符序列中解析位集,并能报告解析错误。

#include <iostream>
#include <bitset>
#include <charconv> // For std::from_chars
#include <array>int main() {const char* str = "11001";std::bitset<8> b;// 使用 std::from_chars 解析auto [ptr, ec] = std::from_chars(str, str + std::strlen(str), b, 2); // 2 表示二进制基数if (ec == std::errc{}) {std::cout << "Parsed successfully: " << b << std::endl;std::cout << "Stopped at character: '" << *ptr << "'" << std::endl;} else if (ec == std::errc::invalid_argument) {std::cout << "Invalid binary string!" << std::endl;} else if (ec == std::errc::result_out_of_range) {std::cout << "String too long for bitset size!" << std::endl;}// 尝试解析包含非法字符的字符串const char* invalid_str = "110x1";std::bitset<8> b_invalid;auto [ptr2, ec2] = std::from_chars(invalid_str, invalid_str + std::strlen(invalid_str), b_invalid, 2);if (ec2 != std::errc{}) {std::cout << "Parsing failed as expected for '110x1'" << std::endl;}return 0;
}

输出:

Parsed successfully: 00011001
Stopped at character: ''
Parsing failed as expected for '110x1'

说明:

  • std::from_chars 提供了更安全、更高效的解析方式。
  • 它返回一个 std::from_chars_result,包含一个指向停止解析位置的指针 ptr 和一个错误码 ec
  • 这使得你可以精确地知道解析是否成功以及在哪里停止。

示例 3:常用操作方法

#include <iostream>
#include <bitset>int main() {std::bitset<8> b("10101010");std::cout << "Original: " << b << std::endl;// 1. 访问单个位std::cout << "Bit at pos 0: " << b[0] << std::endl; // 最右边是低位 (pos 0)std::cout << "Bit at pos 7: " << b[7] << std::endl; // 最左边是高位 (pos 7)// 2. 修改单个位b[1] = 1; // Set bit 1 to 1b.set(3); // Set bit 3 to 1b.reset(5); // Set bit 5 to 0b.flip(7); // Toggle bit 7std::cout << "After modifications: " << b << std::endl;// 3. 批量操作b.set();     // Set all bits to 1std::cout << "All set: " << b << std::endl;b.reset();   // Set all bits to 0std::cout << "All reset: " << b << std::endl;b.flip();    // Flip all bits (now all 1s)std::cout << "All flipped: " << b << std::endl;// 4. 查询std::cout << "Count of 1s: " << b.count() << std::endl; // 应该是 8std::cout << "Size: " << b.size() << std::endl;         // 8std::cout << "All bits are 1? " << b.all() << std::endl; // truestd::cout << "Any bit is 1? " << b.any() << std::endl;   // truestd::cout << "No bit is 1? " << b.none() << std::endl;   // falsereturn 0;
}

输出:

Original: 10101010
Bit at pos 0: 0
Bit at pos 7: 1
After modifications: 00101111
All set: 11111111
All reset: 00000000
All flipped: 11111111
Count of 1s: 8
Size: 8
All bits are 1? 1
Any bit is 1? 1
No bit is 1? 0

示例 4:位运算

std::bitset 支持标准的位运算符。

#include <iostream>
#include <bitset>int main() {std::bitset<8> a("11001100");std::bitset<8> b("10101010");std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;// 位与std::cout << "a & b: " << (a & b) << std::endl; // 10001000// 位或std::cout << "a | b: " << (a | b) << std::endl; // 11101110// 位异或std::cout << "a ^ b: " << (a ^ b) << std::endl; // 01100110// 位非std::cout << "~a: " << (~a) << std::endl;       // 00110011// 左移/右移std::cout << "a << 2: " << (a << 2) << std::endl; // 00110000 (左移2位,低位补0)std::cout << "a >> 2: " << (a >> 2) << std::endl; // 00110011 (右移2位,高位补0)return 0;
}

输出:

a: 11001100
b: 10101010
a & b: 10001000
a | b: 11101110
a ^ b: 01100110
~a: 00110011
a << 2: 00110000
a >> 2: 00110011

示例 5:转换为其他类型

#include <iostream>
#include <bitset>int main() {std::bitset<8> b("10101010"); // 十进制是 170// 转换为 unsigned longunsigned long ul = b.to_ulong();std::cout << "to_ulong(): " << ul << std::endl; // 170// 转换为 unsigned long long (C++11 起)unsigned long long ull = b.to_ullong();std::cout << "to_ullong(): " << ull << std::endl; // 170// 转换为字符串std::string str = b.to_string();std::cout << "to_string(): " << str << std::endl; // "10101010"// 注意:如果位集的值超出了目标类型的范围,to_ulong/to_ullong 会抛出 std::overflow_errortry {std::bitset<64> huge_b;huge_b.set(); // All bits set to 1, value is 2^64 - 1unsigned long bad_ul = huge_b.to_ulong(); // This will throw!} catch (const std::overflow_error& e) {std::cout << "Overflow caught: " << e.what() << std::endl;}return 0;
}

输出:

to_ulong(): 170
to_ullong(): 170
to_string(): 10101010
Overflow caught: bitset::to_ulong

总结

std::bitset 是处理固定长度二进制数据的绝佳选择。C++20 通过引入 std::from_chars 构造支持,极大地增强了其解析能力和错误处理机制,使其在需要从文本输入构建位集的场景下更加健壮和高效。

主要优点:

  • 类型安全: 避免了原始指针和位操作的错误。
  • 可读性强: 代码意图清晰。
  • 功能丰富: 提供了丰富的成员函数进行位操作、查询和转换。
  • 性能良好: 通常由编译器优化为高效的机器指令。

适用场景:

  • 状态标志管理
  • 权限控制
  • 布隆过滤器 (Bloom Filter) 的底层实现
  • 二进制协议解析
  • 任何需要紧凑存储布尔值集合的地方
http://www.dtcms.com/a/438164.html

相关文章:

  • 【数据结构】二叉树的高频热门面试题大全
  • 营口房产建设信息网站网站开发类合同范本
  • 石家庄哪里做网站没有网站怎么做seo
  • Akamai CDN 和 CloudFlare CDN 有什么具体区别?
  • Bash 中的 shopt -s globstar:递归 Glob 模式详解
  • LED驱动芯片FP7208选型指南:参数、应用场景与设计要点(宽压2.5-24V,恒流0.2V)
  • K8s学习----StorageClass:实现存储资源的动态管理
  • JUC 并发编程之无锁模型详解:CAS 原理、原子类应用与 Unsafe 底层实现
  • 网站建设的销售渠道数据库网站 建设方案
  • Python学习之day03学习(文件和异常)
  • 线性代数 · SVD | 导数
  • 免费网页设计成品网站工程建设云
  • wordpress火车头自动分类绍兴百度推广优化排名
  • hadoop-mapreduce编程模型
  • 黄页网站推广公司百度答主招募入口官网
  • AutoOps:简化自管理 Elasticsearch 的旅程
  • python如何批量下载图片
  • PDF中表格的处理 (OCR)
  • 怎样查网站空间地址代理公司注册的价格
  • LangChain源码分析(一)- LLM大语言模型
  • Android setContentView源码与原理分析
  • dlink nas建设网站有什么免费推广项目的好软件
  • 开源 C++ QT QML 开发(一)基本介绍
  • Java学习笔记Day14
  • C++进阶(4)——C++11右值引用和移动语义
  • 从入门到精通【Redis】理解Redis主从复制
  • 公司网站不备案wordpress地址怎么打开
  • 柯西显威:一道最值题的降维打击
  • Java 集合 “Map(2)”面试清单(含超通俗生活案例与深度理解)
  • 网站怎么做悬浮图片放大带后台的网站模板下载