火龙信奥
  • 分享
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

第5天:位运算的魔法(二进制位操作与进阶运算符)

作者: 作者的头像   huolong , 时间:2026-08-27 14:12:01 , 所有人可见, 阅读  52

信息学奥赛(CSP-J)零基础启蒙培训讲义

第5天:位运算的魔法(二进制位操作与进阶运算符)

  • 总时长:6 小时(上午 3 小时,下午 3 小时)
  • 培训目标:通过生动的生活化比喻,帮助零基础学生彻底理解二进制位运算的底层原理(与、或、非、异或、移位),掌握初赛选择题中常考的位运算化简、2的幂次计算以及 x & (x - 1) 的经典骚操作。

📅 上午场:二进制位运算基础(09:00 - 12:00)

一、 为什么要学习位运算?

  • 之前我们学过算术运算(+, -, *, /, %)和逻辑运算(&&, ||, !)。
  • 但是,计算机最底层的灵魂是二进制(0 和 1)。如果你直接去操作这些 0 和 1,就叫做位运算(Bitwise Operations)。
  • 优点:位运算直接在硬件二进制层面上进行,速度极快。在高级算法竞赛和底层系统开发中,用好位运算可以大大优化时间和空间。

二、 四大基本位运算(与、或、非、异或)

在进行位运算时,先把十进制数转成二进制数,然后把每一位上下对齐,按规则进行计算。

1. 按位与(&)

  • 规则:上下两位全都是 1,结果才是 1;只要有一个 0,结果就是 0。
  • 生活比喻:两个人合伙开保险箱,必须两个人都带钥匙(1),保险箱才能打开(1);只要有一个人没带钥匙(0),保险箱就打不开(0)。
  • 例子:计算 5 & 3
  • 先把 5 转成二进制:0101
  • 把 3 转成二进制:0011
  • 上下按位对齐计算:0101 & 0011 = 0001(即十进制的 1)。

2. 按位或(|)

  • 规则:上下两位只要有一个是 1,结果就是 1;只有全都是 0 时,结果才是 0。
  • 生活比喻:家里只要有一个人同意,这事就能通过。
  • 例子:计算 5 | 3
  • 0101 | 0011 = 0111(即十进制的 7)。

3. 按位取反(~)

  • 规则:单目运算符。遇到 0 就变成 1,遇到 1 就变成 0(0 变 1,1 变 0)。
  • 例子:~0 在补码体系下会把所有位翻转。

4. 按位异或(^)—— 计算机里的“魔术师”

  • 规则:上下两位相同为 0,不同为 1。(“异”就是不一样的意思,不一样就是 1)。
  • 三大核心性质(初赛大热考点):
  • 任何数和 0 做异或,值不变:x ^ 0 = x。
  • 任何数和自己做异或,结果为 0:x ^ x = 0。
  • 满足交换律和结合律:a ^ b ^ a = b(经常用来做不使用第三个变量的数字交换,或者在海量数据中找出落单的那个数)。

---

📅 下午场:移位运算与位运算经典骚操作(14:00 - 17:00)

一、 移位运算符(<< 与 >>)

除了按位操作,我们还可以把二进制整体往左或者往右“推”。

1. 左移运算符(<<)

  • 规则:把二进制的所有位整体往左边推,右边空出来的地方补 0。
  • 数学意义:在没有溢出的前提下,左移一位相当于把原数字乘以 2。
  • 例子:3 << 1(3 的二进制是 0011,左移一位变成 0110,即十进制的 6,也就是 $3 \times 2^1 = 6$)。
  • 3 << 2 就是乘以 $2^2 = 4$,结果为 12。

2. 右移运算符(>>)

  • 规则:把二进制的所有位整体往右边推,左边高位补符号位(正数补 0,负数通常补 1)。
  • 数学意义:右移一位相当于把原数字整除 2(向下取整)。
  • 例子:5 >> 1(5 的二进制是 0101,右移一位变成 0010,即十进制的 2,也就是 $\lfloor 5 / 2 \rfloor = 2$)。

二、 计算机里的“降龙十八掌”:x & (x - 1)

在历年 CSP-J 初赛的选择题代码中,这段代码出现频率极高:

x = x & (x - 1);
  • 它到底有什么神奇的魔力?
  • 核心作用:把一个整数二进制表示中最右边的那个 1 变成 0。
  • 举个例子推导:
  • 假设 $x = 10$,其二进制是 1010。
  • $x - 1 = 9$,其二进制是 1001(最右边的 1 变成了 0,后面的 0 变成了 1)。
  • 执行 x & (x - 1):1010 & 1001 = 1000(十进制的 8)。
  • 你会发现,原本 1010 里的右边数起第一个 1 直接被消灭了!
  • 初赛怎么考?:
  • 如果题目问:“下面这段代码的功能是什么?” cpp int count = 0; while (x > 0) { count++; x = x & (x - 1); } 答案:统计一个正整数的二进制形式中 1 的个数(也叫求汉明重量 / Popcount)。

---

📝 随堂与课后实战强化练习卷(学生版)

班级:__ 姓名:__ 得分:__

一、 选择题(共 10 题)

  1. 在 C++ 中,表达式 5 & 3 的计算结果是( )。 A. 7 B. 1 C. 5 D. 3

  2. 在 C++ 中,表达式 5 | 3 的计算结果是( )。 A. 7 B. 1 C. 5 D. 3

  3. 下列关于位运算的说法中,错误的是( )。 A. 将一个正整数向左移位 1 位,其等价于该数乘以 2(在不溢出的前提下) B. 将一个正整数向右移位 1 位,其等价于该数除以 2 并向下取整 C. 任何整数与 0 进行按位异或(^)运算,结果都等于它本身 D. 任何整数与自己进行按位异或(^)运算,结果都等于它本身

  4. 设 x = 12(对应的二进制为 1100),执行 x = x & (x - 1) 后,x 的十进制值是( )。 A. 12 B. 11 C. 8 D. 4

  5. 下列代码段的功能是( )。 cpp int solve(int n) { int ans = 0; while (n > 0) { ans++; n = n & (n - 1); } return ans; } A. 计算 $n$ 减去 1 后的值 B. 统计 $n$ 的二进制表示中有多少个位是 1 C. 判断 $n$ 是不是 2 的幂次 D. 找出 $n$ 的二进制表示中最右边的 1

  6. 在 C++ 中,表达式 12 << 1 的计算结果是( )。 A. 6 B. 12 C. 24 D. 48

  7. 在 C++ 中,表达式 13 >> 1 的计算结果是( )。 A. 6 B. 7 C. 13 D. 26

  8. 设 a = 5(二进制 0101),b = 6(二进制 0110),则表达式 a ^ b 的二进制结果转换为十进制是( )。 A. 1 B. 3 C. 7 D. 11

  9. 下列哪个表达式可以用来高效地判断一个正整数 $n$ 是不是 2 的整数次幂(例如 2, 4, 8, 16 等)?( ) A. n % 2 == 0 B. (n & (n - 1)) == 0 C. (n | (n - 1)) == 0 D. (n ^ (n - 1)) == 0

  10. 设无符号整型变量 x = 255,执行 cout << (x & (x - 1)); 后,输出的结果是( )。 A. 255 B. 254 C. 128 D. 0


(注:教师答案与详细解析页在下方,建议打印前单独切分)

\newpage


📖 课后练习卷 —— 标准答案与详细解析

  1. 正确答案:B
  2. 详细解析:

    • 5 的二进制是 0101,3 的二进制是 0011。
    • 按位与(&)规则:全 1 才为 1。
    • 0101 & 0011 = 0001,对应的十进制结果是 1。故选 B。
  3. 正确答案:A

  4. 详细解析:

    • 5 的二进制是 0101,3 的二进制是 0011。
    • 按位或(|)规则:有 1 个为 1 就是 1。
    • 0101 | 0011 = 0111,对应的十进制结果是 7。故选 A。
  5. 正确答案:D

  6. 详细解析:

    • 任何整数与自己异或结果应该是 0(而不是它本身),因此选项 D 说“结果等于它本身”是错误的。其余选项 A、B、C 均表述正确。
  7. 正确答案:C

  8. 详细解析:

    • x = 12,二进制为 1100。
    • x - 1 = 11,二进制为 1011。
    • 1100 & 1011 = 1000,对应的十进制数值是 8。该操作成功消除了最右边的一个 1。故选 C。
  9. 正确答案:B

  10. 详细解析:

    • 循环每次执行 n = n & (n - 1) 都会消去 $n$ 二进制中最右边的一个 1,同时 ans(计数器)自增 1,直到 $n$ 变为 0。因此该函数的作用是统计 $n$ 二进制中 1 的个数。故选 B。
  11. 正确答案:C

  12. 详细解析:

    • 12 << 1 表示左移一位,相当于 $12 \times 2 = 24$。故选 C。
  13. 正确答案:A

  14. 详细解析:

    • 13 >> 1 表示右移一位,相当于 $\lfloor 13 / 2 \rfloor = 6$。故选 A。
  15. 正确答案:D

  16. 详细解析:

    • a = 0101,b = 0110。
    • 按位异或(^)规则:相同为 0,不同为 1。
    • 0101 ^ 0110 = 0011(等等,按位算:第4位 0^0=0,第3位 1^1=0,第2位 0^1=1,第1位 1^0=1,不对:
    • 0101
    • 0110
    • 异或结果:0011?不对,从右往左看:
      • 最右边(第1位):1 ^ 0 = 1
      • 第2位:0 ^ 1 = 1
      • 第3位:1 ^ 1 = 0
      • 第4位:0 ^ 0 = 0
    • 组合起来是 0011 吗?再算一遍:
      • 5 = 0101
      • 6 = 0110
      • 异或:第一位 1^0=1,第二位 0^1=1,第三位 1^1=0,第四位 0^0=0 -> 二进制 0011 即十进制 3?等等,二进制从右向左:
      • 第 0 位(个位):1 ^ 0 = 1
      • 第 1 位(2的1次方):0 ^ 1 = 1
      • 第 2 位(2的2次方):1 ^ 1 = 0
      • 第 3 位(2的3次方):0 ^ 0 = 0
      • 拼起来是 0011 没错,值为 3。因此本题选 B。(注:若原题选项设计对应正确对齐,5^6 = 3)。
  17. 正确答案:B

  18. 详细解析:

    • 2 的幂次方的数字,其二进制表示中有且仅有一个 1(例如:2=10, 4=100, 8=1000)。
    • 如果对它执行 n & (n - 1),这个唯一的 1 就会被消灭,结果刚好变成 0。因此 (n & (n - 1)) == 0 是判断 2 的幂次的经典写法。故选 B。
  19. 正确答案:B

    • 详细解析:
    • x = 255,其二进制是全 1 的 8 位数 11111111。
    • x - 1 = 254,二进制是 11111110。
    • 255 & 254 刚好消灭了最右边的一个 1,结果为 254。故选 B。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

关于火龙

  • 关于我们
  • 学员获奖
  • 预约试听
  • ACM课程
  • CSP课程
  • 学习指南

帮助中心

  • 用户协议
  • 打字练习
  • 在线画图
  • DevC++下载
  • CSP报名
  • GESP官网

推荐课程

  • C++零基础入门(可试看)
  • C++进阶提升
  • GESP考级辅导
  • GESP打卡
  • CSP-J/S打卡

公众号

火龙信奥公众号二维码

地址:义乌市北门街188号新天地商厦二楼2F 邮箱:wdlok305@126.com

© 2017-2026 义乌市睿码科技有限公司版权所有 浙ICP备2021013995号

火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码