关于异或(^)、按位与(&)和逻辑与(&&)的区别及使用场景。以下是分层次的解析:
1. 运算符的核心区别
| 运算符 | 名称 | 操作对象 | 计算规则 | 示例(C++) |
|---|---|---|---|---|
^ | 按位异或 | 整数类型 | 对应位相同为0,不同为1 | 5 ^ 3 → 6(101 ^ 011 = 110) |
& | 按位与 | 整数类型 | 对应位均为1时为1,否则为0 | 5 & 3 → 1(101 & 011 = 001) |
&& | 逻辑与 | 布尔表达式 | 左右表达式均为true时结果为true,否则false | (a > 0) && (b < 0) |
2. 具体用途与场景
(1) 异或(^)
• 特性:
• 满足交换律和结合律:a ^ b ^ a = b
• 自反性:a ^ a = 0,a ^ 0 = a
• 典型应用:
• 交换两个数(无需临时变量):
```cpp
a ^= b; b ^= a; a ^= b; // 交换a和b的值
```
• 简单加密:通过密钥异或数据(可逆操作)。
• 找不重复的数字:如LeetCode 136题(其他数字出现两次,找出单次出现的数)。
(2) 按位与(&)
• 特性:
• 可用于掩码操作(提取特定位)。
• 判断奇偶性:n & 1 → 结果为1则为奇数。
• 典型应用:
• 权限控制:用位掩码表示权限组合(如READ=1<<0, WRITE=1<<1)。
• 清零最低位的1:n & (n - 1)(用于统计二进制中1的个数)。
(3) 逻辑与(&&)
• 特性:
• 短路求值:若左操作数为false,右操作数不会执行。
• 仅用于布尔上下文(非零值隐式转换为true)。
• 典型应用:
• 条件判断:如if (ptr != nullptr && ptr->isValid())。
• 链式检查:避免多层嵌套if。
3. 底层实现对比
| 运算符 | CPU指令 | 性能注意 |
|---|---|---|
^/& | 单周期位操作指令 | 极快,通常1个时钟周期完成 |
&& | 条件跳转指令 | 短路求值可能减少分支预测失败的开销 |
示例汇编代码(x86):
; 异或操作示例
mov eax, 5 ; a = 5
xor eax, 3 ; a ^= 3 → eax = 6
; 逻辑与短路求值
cmp [ptr], 0 ; 检查ptr是否为null
je false_label ; 如果为null,跳转到false分支
call [ptr+isValid_offset] ; 否则调用isValid()
4. 面试常见问题
Q1: 如何用^判断两个数符号是否相反?
bool is_opposite_sign(int a, int b) {
return (a ^ b) < 0; // 最高位不同时结果为1(负数)
}
Q2: &和&&在布尔表达式中的区别?
• &会强制计算两侧表达式(无短路),适合需要副作用的场景。
• &&是短路求值,更高效且安全(如避免空指针解引用)。
Q3: 如何用&实现模运算?
int mod_power_of_two(int n, int d) {
return n & (d - 1); // 仅当d是2的幂时成立(如d=8 → n%8 = n&7)
}
5. 总结
• 用^:需要位级操作或数学特性(如交换、去重)。
• 用&:位掩码处理或硬件寄存器操作。
• 用&&:逻辑条件判断,优先选择(短路特性更安全)。
3万+

被折叠的 条评论
为什么被折叠?



