c++位运算符共6种:&(按位与,同1得1,用于检测位)、|(按位或,有1得1,用于置位)、^(按位异或,不同得1,用于翻位或交换)、~(按位取反,0变1、1变0)、(右移,无符号数等价除2ⁿ,有符号数通常算术右移)。

位运算符有哪些,各自干啥用
位运算符直接操作整数的二进制位,速度快、内存省,常用于状态标记、权限控制、加密算法或硬件寄存器操作。C++里常用的有:&(按位与)、|(按位或)、^(异或)、~(取反)、(左移)、<code>>>(右移)。
注意:& 和 && 完全不同——前者是位运算,后者是逻辑与;同理 | ≠ ||。新手常在这儿翻车,一写错就逻辑异常还难调试。
-
&常用于“检查某位是否为 1”,比如flags & 0x04判断第 3 位(从 0 开始)是否置位 -
|用于“设置某位”,如flags | 0x08把第 4 位设为 1(不干扰其他位) -
^可翻转特定位(flags ^ 0x02),也常用于交换两个整数(不用临时变量) - 左移
等价于乘以 2 的幂,右移 <code>>>对无符号数等价于除以 2 的幂;但对有符号负数,右移行为由编译器定义(通常算术右移),别依赖它做数学计算
怎么安全地用位运算操作标志位
用整型变量当“位图”存多个布尔状态,比开一堆 bool 成员更省内存,也更适合跨平台协议传输。
推荐定义清晰的掩码常量,别硬写十六进制数字:
enum Flag {
READABLE = 1
- 检查是否具备某权限:
if (perms & EXECUTABLE)—— 注意这里不能写成== EXECUTABLE,因为可能同时有多个标志位被设 - 添加权限:
perms |= EXECUTABLE - 清除权限:
perms &= ~EXECUTABLE(先取反再与) - 翻转权限:
perms ^= READABLE - 务必确保底层类型足够宽(比如用
uint32_t而非char),避免移位溢出
左移右移容易踩的坑
移位不是万能乘除替代品,尤其在边界和类型上极易出错。
- 移位位数不能为负,也不能 ≥ 操作数位宽(如对
int移 32 位在 32 位系统上未定义) 1 在 <code>int上是负数(符号位被置),想得到大正数得用1U 或 <code>1ULL- 右移有符号数时,高位补的是符号位(算术右移),
-8 >> 1结果是-4,但标准不强制要求这点,所以移植到某些嵌入式平台可能表现不同 - 避免对
short或char直接移位:它们会先整型提升(int),结果可能和预期不符,显式转成unsigned int更可控
异或的实用技巧和陷阱
^ 是唯一可逆的位运算,这个特性让它很特别。
- 交换两个变量(无临时变量):
a ^= b; b ^= a; a ^= b;—— 但仅适用于不同地址的变量,swap(x, x)会让x变成 0 - 快速清零:
x ^= x结果恒为 0,比x = 0少一次内存写入(某些场景有微优化价值) - 实现简单加密:
data[i] ^= key加密,再一遍同样操作就解密 —— 但这是玩具级,别用在真实安全场景 - 注意优先级:
a & b ^ c等价于(a & b) ^ c,不是a & (b ^ c);不确定时加括号,别靠记优先级
位运算本身不难,难的是意识到什么时候该用、用在哪、以及类型和符号怎么配合。最常被忽略的是整型提升和有符号移位的可移植性——同一段代码在 x86 和 ARM 上可能行为一致,但在某些 DSP 或老款单片机上就出问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











