C++位操作
位操作是程序员的“超能力”之一。它允许我们深入到数据的最底层,直接操控二进制位,从而实现高效的算法、紧凑的数据存储和底层的硬件交互。C++ 语言提供了一套丰富且不断进化的工具集来支持位操作,从经典的位运算符到 C++20 引入的高性能函数,应有尽有。
本文将系统性地介绍 C++ 中所有与位操作相关的函数和工具,分为四个类别,并提供清晰的示例,帮助你彻底掌握它们。
基础核心:位运算符
这是所有位操作的基石。它们是 C++ 内置的运算符,直接对整数类型进行操作。
示例
函数式编程的优雅:<functional> (C++14)
为了让位运算能与 STL 算法(如 std::accumulate)无缝协作,C++14 在 <functional> 头文件中引入了一组函数对象。
std::bit_and<T>: 执行按位与 (&)。std::bit_or<T>: 执行按位或 (|)。std::bit_xor<T>: 执行按位异或 (^)。std::bit_not<T>: 执行按位取反 (~)。
它们的主要优势在于作为“可调用对象”传递,使代码更具表现力。
示例:计算向量中所有元素的异或和
现代 C++的高性能工具箱:<bit> (C++20)
C++20 带来了革命性的 <bit> 头文件,提供了一组高效的底层位操作函数,它们通常能直接映射到现代 CPU 的硬件指令,性能极高。
std::popcount(n): 计算n中值为 1 的位的数量("population count")。std::has_single_bit(n): 检查n是否是 2 的幂(即是否只有一个位是 1)。std::countl_zero(n)/std::countr_zero(n): 分别计算从左(高位)或从右(低位)开始的连续 0 的数量。std::bit_ceil(n)/std::bit_floor(n): 分别计算大于等于nの最小的 2 的幂和小于等于n的最大的 2 的幂。std::rotl(n, s)/std::rotr(n, s): 将n循环左移或右移s位。
示例
面向对象的位容器:<bitset>
std::bitset 是一个类模板,用于管理一个固定大小的位序列。它像一个 bool 数组,但为位操作进行了空间和性能优化,并提供了丰富的成员函数。
- 构造: 可以从整数、字符串等创建。
- 访问与修改:
[],set(),reset(),flip()。 - 查询:
count(),size(),any(),none(),all()。 - 转换:
to_string(),to_ulong(),to_ullong()。
示例
总结
如何选择?
- 日常简单操作: 直接使用位运算符 (
&,|,^等)。 - 需要与 STL 算法集成: 使用
<functional>中的函数对象。 - 追求极致性能或需要高级位操作 (如
popcount, 循环移位): 优先使用 C++20 的<bit>库。 - 需要管理一组状态标志或构建位掩码:
std::bitset是最清晰、最安全的选择。
通过掌握这些工具,你可以在 C++ 中编写出更高效、更优雅、更底层的代码。希望这篇指南能成为你探索位操作世界的得力助手!