[随时更新] & | ~ ^ 位运算的蛋疼妙用

本文介绍两种不使用临时变量交换数值的方法,并提供一种不使用比较语句求两个数中较大数的算法。适用于编程基础学习。

1. 交换两个数但不能使用临时变量

// method 1

void swap (int* a, int* b) {

    *a ^= *b; *b ^= *a; *a ^= *b;

}

 

// method 2

void swap (int* a, int* b) { // 乘号改成加号时,除号改成减号。

          // 当 *a 和 *b 都很大时,第一句可能会溢出。

    *a *= *b; *b = *a / *b; *a /= *b;

}

 

2. 求两个数中较大的一个但不能使用比较语句

 

int max (int a, int b) { // a 与 b 的符号必须相同

    return a ^ b | a;

}

<think> 我们被要求解释运算符 &, ^, |, ~ 在编程中的含义和用法。这些是位运算符,用于对整数的二进制进行操作。根据引用内容,虽然引用主要讨论逻辑运算符(&&, ||),但它们也提到了非短路运算符(&, |)用于位运算。我们将扩展到位运算&, |, ^(异或)和 ~(按取反)。 1. & (按与): 对两个操作数的每一进行与操作。规则是:1 & 1 = 1, 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0。 例如:5 & 3 -> 二进制:101 & 011 = 001 -> 1 2. | (按或): 对两个操作数的每一进行或操作。规则是:1 | 1 = 1, 1 | 0 = 1, 0 | 1 = 1, 0 | 0 = 0。 例如:5 | 3 -> 101 | 011 = 111 -> 7 3. ^ (按异或): 对两个操作数的每一进行异或操作。规则是:相同为0,不同为1。即:1 ^ 1 = 0, 1 ^ 0 = 1, 0 ^ 1 = 1, 0 ^ 0 = 0。 例如:5 ^ 3 -> 101 ^ 011 = 110 -> 6 4. ~ (按取反): 一元运算符,对操作数的每一取反。规则是:0变成1,1变成0。注意,在计算机中整数通常用补码表示,所以取反操作会包括符号。 例如:~5 -> 在32系统中,5的二进制为00000000000000000000000000000101,取反后为11111111111111111111111111111010,这是一个负数(补码),转换成十进制是-6(因为负数的补码是取反加1,所以反过来,这里取反后相当于-6)。 另外,这些运算符也可以用于布尔值,但注意: - 对于布尔值,&和|作为非短路逻辑运算符(即两边都会计算),而^用于布尔值的异或(相同为false,不同为true)。但通常逻辑运算我们使用&&和||(短路版本)更常见,以避免不必要的计算和副作用(如引用[1][2][3]所述)。 应用场景: - 权限控制:使用掩码,每个代表一种权限。例如,用1表示读,2表示写,4表示执行。那么权限组合可以用或运算:读|写=3。检查权限用与:若用户权限&读不为0则有读权限。 - 加密/哈希:异或运算常用于简单的加密,因为同一个数异或两次得到原值。 - 图形处理:例如,图像混合时使用位运算进行像素操作。 - 优化:位运算通常比算术运算快,在底层代码或算法优化中使用。 注意:位运算符通常用于整数类型(byte, short, int, long等),而布尔值也可以使用,但布尔值的位运算与整数位运算意义不同(布尔值只有一)。 下面给出示例代码(以Java为例,但位运算符在大多数语言中类似): </think> ### 位运算符 `&`、`^`、`|`、`~` 的编程含义与用法 位运算符直接操作整数的二进制,适用于底层优化、硬件交互和算法实现。核心原理如下表: | 运算符 | 名称 | 规则描述 | 示例(二进制) | 数值结果 | |--------|--------------|------------------------------|---------------------------|----------| | `&` | **按与** | 同1则1,否则0 | `1010 & 1100 = 1000` | 10 & 12 = 8 | | `\|` | **按或** | 有1则1,同0则0 | `1010 \| 1100 = 1110` | 10 \| 12 = 14 | | `^` | **按异或** | 相同为0,不同为1 | `1010 ^ 1100 = 0110` | 10 ^ 12 = 6 | | `~` | **按取反** | 0变1,1变0(一元操作) | `~1010 = 0101`(4示例) | ~10 = -11 | --- ### 一、详细用法及示例 #### 1. `&`(按与) - **功能**:筛选共同,常用于掩码操作和权限控制 - **示例**:提取低4 ```python num = 0b11011010 # 十进制 218 mask = 0b00001111 # 十进制 15 result = num & mask # → 0b00001010 (十进制 10) ``` - **应用场景**: - 网络协议解析(如IP地址子网掩码) - 硬件寄存器状态检查[^1] #### 2. `|`(按或) - **功能**:合并标志,用于组合权限 - **示例**:设置权限 ```java int READ = 0b001; // 1 int WRITE = 0b010; // 2 int perms = READ | WRITE; // → 0b011 (十进制 3) ``` - **应用场景**: - 文件系统权限控制(如Linux权限) - 图形渲染中的颜色混合[^2] #### 3. `^`(按异或) - **功能**:切换特定,特性:$a \oplus b \oplus b = a$ - **示例**:简易加密/解密 ```c char data = 'A'; // 二进制 01000001 char key = 0b11111111; // 255 char encrypted = data ^ key; // 10111110 (加密) char decrypted = encrypted ^ key; // 还原 'A' ``` - **应用场景**: - 数据加密(如简单XOR加密) - 交换变量值(无需临时变量): ```python a = 5; b = 3 a ^= b # a = 6 b ^= a # b = 5 a ^= b # a = 3 ``` #### 4. `~`(按取反) - **功能**:翻转所有(含符号) - **注意**:结果依赖整数表示(补码) - **示例**(8有符号整数): ```python num = 10 # 二进制 00001010 result = ~num # → 11110101 → 十进制 -11 ``` - **应用场景**: - 生成掩码的反码(如 `mask = 0xFF; ~mask`) - 算法中的翻转优化[^4] --- ### 二、关键特性对比 | 特性 | `&` | `\|` | `^` | `~` | |--------------|--------------|--------------|--------------|--------------| | 交换律 | ✔️ | ✔️ | ✔️ | ❌(一元) | | 结合律 | ✔️ | ✔️ | ✔️ | — | | 近似布尔逻辑 | AND | OR | XOR | NOT | | 特殊性质 | 清零特定 |特定 | 两次操作还原 | 数值关系:$ \sim n = -n-1 $ | > **注**:位运算符优先级通常低于算术运算符,建议用括号明确逻辑,如 `(a + b) & mask`。 --- ### 三、典型应用场景 1. **权限系统** 用组合表示权限集(如 `READ=1`, `WRITE=2`, `EXECUTE=4`),通过 `\|` 授权、`&` 验权、`& ~` 撤权: ```java int userPerms = READ | EXECUTE; // 授权:0b101 boolean canRead = (userPerms & READ) != 0; // 检查:true userPerms &= ~EXECUTE; // 撤销执行权限 → 0b001 ``` 2. **硬件编程** 嵌入式开发中操作寄存器: ```c #define LED_ON (1 << 5) // 第5控制LED PORT |= LED_ON; // 点亮LED PORT &= ~LED_ON; // 熄灭LED ``` 3. **算法优化** - 奇偶判断:`(n & 1) == 0` 等价于 `n % 2 == 0` - 快速乘除:`n << k` = $n \times 2^k$,`n >> k` = $\lfloor n / 2^k \rfloor$(非负整数)[^5] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值