C语言学习日记 · 位运算篇
- 一、学习概述
- 二、6 种位运算符详解
- 1\. 按位与 `&`
- 2\. 按位或 `|`
- 3\. 按位异或 `^`
- 经典应用 1:找出唯一出现一次的数字
- 经典应用 2:无临时变量交换两个整数
- 4\. 按位取反 `~`
- 5\. 左移 `<<`
- 6\. 右移 `>>`
- 三、掩码(mask)核心用法
- 1\. 掩码概念
- 2\. 三大标准操作
- 3\. 常用掩码生成
- 四、易错踩坑总结
- 五、练习与验证
一、学习概述
本次学习了 C 语言全部 6 种位运算符,这类运算直接操作整数的二进制每一位,运算效率极高,在底层开发、嵌入式寄存器操作、算法题中高频出现。所有位运算均基于整数的补码进行,默认 32 位 int 类型参与运算。
二、6 种位运算符详解
1. 按位与&
运算规则:对应二进制位全 1 才为 1,有 0 则为 0
核心用途:保留指定位、清零指定位、判断某一位是否为 1
示例:
6 & 30110 (6) & 0011 (3) ---------- 0010 (2)常用写法:判断数字 x 的第 n 位是否为 1
if((x&(1<<n))!=0){// 第n位为1}
2. 按位或|
运算规则:对应二进制位有 1 则为 1,全 0 才为 0
核心用途:将指定位置为 1,其余位保持不变
示例:
6 | 30110 (6) | 0011 (3) ---------- 0111 (7)常用写法:把 x 的第 n 位置 1
x=x|(1<<n);
3. 按位异或^
运算规则:对应二进制位不同为 1,相同为 0
三大核心性质
x ^ x = 0:相同数字异或直接抵消x ^ 0 = x:数字异或 0 等于自身满足交换律、结合律,运算顺序不影响最终结果
经典应用 1:找出唯一出现一次的数字
题目:一组数字中只有 1 个数出现 1 次,其余都出现 2 次,找出这个数。
输入示例:5 7 6 6 5
解法:所有数字连续异或,成对的数相互抵消为 0,最终结果就是只出现一次的数
演算过程:
完整代码
#include<stdio.h>intmain(){intn1,n2,n3,n4,n5;scanf("%d%d%d%d%d",&n1,&n2,&n3,&n4,&n5);intans=n1^n2;ans=ans^n3;ans=ans^n4;ans=ans^n5;printf("消失的数字是:%d\n",ans);return0;}
经典应用 2:无临时变量交换两个整数
初始值:a=13,b=9
三步交换代码
a=a^b;b=a^b;a=a^b;逐行演算
a = 13^9 = 4,此时a=4, b=9b = 4^9 = 13,b 拿到原 a 的值,此时a=4, b=13a = 4^13 = 9,a 拿到原 b 的值,最终a=9, b=13
坑点提醒:若 a 和 b 是同一个变量(同一块内存),执行后值会直接清零;该写法可读性差,实际工程更推荐用临时变量交换。
4. 按位取反~
运算规则:单目运算符,将二进制每一位0 变 1,1 变 0
速算公式:
~a = -(a + 1)示例:
a=10,~10 = -11完整原理(32 位 int)
10 的原码:
00000000 00000000 00000000 00001010按位取反后:
11111111 11111111 11111111 11110101最高位为 1,代表负数;按补码规则换算后得到十进制值
-11
易错区分:
~和!运算符 类型 作用 示例 ~按位取反 操作每一个二进制位 ~10 = -11!逻辑取反 只判断真假,非 0 变 0,0 变 1 !10 = 0
5. 左移<<
运算规则:二进制整体向左移动 n 位,高位丢弃,低位补 0
数值效果:无溢出前提下,左移 n 位等价于乘以 2 的 n 次方
示例:
6 << 1 = 12,6 << 2 = 24
6. 右移>>
运算规则:二进制整体向右移动 n 位,低位丢弃;正数高位补 0,负数高位补符号位(算术右移,主流编译器默认)
数值效果:右移 n 位等价于除以 2 的 n 次方(整数向下取整)
示例:
6 >> 1 = 3,6 >> 2 = 1
三、掩码(mask)核心用法
1. 掩码概念
掩码是一个二进制模板数字,配合位运算符可以精准操作指定的某一位或某几位,同时完全不影响其他位,是嵌入式、寄存器操作的核心手段。
2. 三大标准操作
| 操作 | 代码 | 掩码特点 | |
|---|---|---|---|
| 第 n 位置 1 | `x = x | (1 << n)` | 掩码仅第 n 位为 1 |
| 第 n 位清零 | x = x & ~(1 << n) | 掩码仅第 n 位为 0,其余全 1 | & |
| 第 n 位翻转 | x = x ^ (1 << n) | 掩码仅第 n 位为 1 | ^ |
3. 常用掩码生成
1 << n:只有第 n 位为 1,其余为 0~(1 << n):只有第 n 位为 0,其余全 1~0:所有二进制位全为 1 的通用掩码
四、易错踩坑总结
位运算不会修改原变量,必须通过赋值保存结果,例如单独写
~a;不会改变 a 的值禁止用 4 位二进制脑补运算结果,int 为 32 位,高位全部参与运算,正数取反必然得到负数
异或交换变量有局限性,不能用于同一个变量、浮点数,工程开发优先使用临时变量
移位运算符优先级低于加减运算,复杂表达式注意加括号
~是按位取反,!是逻辑取反,二者功能完全不同,不可混用
五、练习与验证
口算:
~5的结果是多少?口算:数字
2 3 2 4 4全部异或,最终结果是多少?写代码:将整数 x 的第 3 位清零,其余位保持不变。