当前位置: 首页 > article >正文

ccf中学生计算机程序设计入门篇课后题p164页test(1)-2 输入一个数,统计这个数二进制中1的个数

include <iostream>
using namespace std;int main() {int x;int n = 0;// 输入数据cin >> x;// 统计x二进制中1的个数for (n = 0; x != 0; x &= x - 1) {n++;}// 输出结果cout << n << endl;return 0;
}

程序解释:

  1. 输入:程序从标准输入读取一个整数 x
  2. 统计二进制中1的个数
    • 使用 for 循环,初始条件为 n = 0
    • 循环条件为 x != 0
    • 每次循环,x 更新为 x &= x - 1,这一步会去掉 x 的二进制表示中最低位的 1
    • 每次循环,n 增加 1,表示找到一个 1
  3. 输出:循环结束后,输出 n,即 x 的二进制表示中 1 的个数。

当我们输入 3 时,程序的运行步骤和变量变化如下:

初始状态:

  • x = 3 (输入的十进制数)
  • n = 0 (用于统计二进制中 1 的个数)

二进制表示:

  • 3 的二进制表示为 11

运行步骤:

  1. 第一次循环:

    • x = 3 (二进制:11
    • x - 1 = 2 (二进制:10
    • x &= x - 13 & 2,结果为 2 (二进制:10
    • n++n0 变为 1
  2. 第二次循环:

    • x = 2 (二进制:10
    • x - 1 = 1 (二进制:01
    • x &= x - 12 & 1,结果为 0 (二进制:00
    • n++n1 变为 2
  3. 循环结束:

    • x = 0,循环条件 x != 0 不满足,退出循环

最终状态:

  • x = 0
  • n = 2

输出结果:
程序输出 2,表示 3 的二进制表示中有 21

总结:

  • 输入 3,其二进制为 11,包含 21
  • 程序通过 x &= x - 1 的操作,每次消除二进制表示中最右边的 1,直到 x 变为 0,最终统计出 1 的个数为 2

你: 这个for循环,一开始是输入3,满足下x!=0的条件不应该是n++,n变成1吗?还是?到底这个for循环的执行顺序是什么?

你提到的代码是用来统计一个整数的二进制表示中1的个数。为了帮助你更好地理解这个for循环的执行顺序,我们来详细分析一下代码的执行过程,特别是for循环的执行顺序。

代码分析

include <iostream>
using namespace std;int main() {int x;int n = 0;// 输入数据cin >> x;  // 假设输入的是3// 统计x二进制中1的个数for (n = 0; x != 0; x &= x - 1) {n++;}// 输出结果cout << n << endl;return 0;
}

执行步骤

  1. 初始化

    • x 被赋值为3(假设用户输入3)。
    • n 被初始化为0。
  2. for循环的执行顺序

    • for循环的语法是:for (初始化; 条件; 更新) { 循环体 }
    • 在每次循环开始时,首先检查条件(x != 0),如果条件为真,则执行循环体,然后执行更新部分(x &= x - 1),接着再次检查条件,以此类推。
  3. 第一次循环

    • 条件检查x != 0(3 != 0),条件为真,进入循环体。
    • 循环体n++n从0变为1。
    • 更新x &= x - 1,即 x = x & (x - 1)
      • x - 1 的结果是2(3 - 1 = 2)。
      • x & (x - 1)3 & 2,即 0b11 & 0b10 = 0b10,所以 x 被更新为2。
  4. 第二次循环

    • 条件检查x != 0(2 != 0),条件为真,进入循环体。
    • 循环体n++n从1变为2。
    • 更新x &= x - 1,即 x = x & (x - 1)
      • x - 1 的结果是1(2 - 1 = 1)。
      • x & (x - 1)2 & 1,即 0b10 & 0b01 = 0b00,所以 x 被更新为0。
  5. 第三次循环

    • 条件检查x != 0(0 != 0),条件为假,循环结束。

变量变化

循环次数x 的二进制x 的十进制n 的值
初始化0b1130
第一次0b1021
第二次0b0002

最终输出

程序最终输出 n 的值,即 2

总结

  • for循环的执行顺序是:初始化 → 条件检查 → 循环体 → 更新 → 条件检查 → 循环体 → 更新 → …
  • 在这个例子中,for循环会执行两次,每次循环都会减少x中1的个数,并增加n的值,直到x变为0。

希望这个解释能帮助你更好地理解for循环的执行顺序和代码的工作原理!


你: 很好,n是4095的时候,列一下for运行过程

我们来看一下当 x = 4095 时,for 循环的执行过程。x = 4095 的二进制表示是 111111111111,共有 12 个 1

for 循环的执行顺序:

for (n = 0; x != 0; x &= x - 1) {n++;
}
  1. 初始化n = 0
  2. 条件判断:检查 x != 0。如果为真,执行循环体;否则退出循环。
  3. 循环体n++
  4. 更新表达式x &= x - 1
  5. 重复步骤 2-4,直到 x == 0

具体执行过程(x = 4095):
初始值:

  • x = 4095(二进制:111111111111
  • n = 0

第 1 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 1
  3. 更新表达式x &= x - 1,即 x = 4095 & 4094
    • 4095 的二进制:111111111111
    • 4094 的二进制:111111111110
    • 按位与结果:111111111110,即 x = 4094

第 2 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 2
  3. 更新表达式x &= x - 1,即 x = 4094 & 4093
    • 4094 的二进制:111111111110
    • 4093 的二进制:111111111101
    • 按位与结果:111111111100,即 x = 4092

第 3 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 3
  3. 更新表达式x &= x - 1,即 x = 4092 & 4091
    • 4092 的二进制:111111111100
    • 4091 的二进制:111111111011
    • 按位与结果:111111111000,即 x = 4088

第 4 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 4
  3. 更新表达式x &= x - 1,即 x = 4088 & 4087
    • 4088 的二进制:111111111000
    • 4087 的二进制:111111110111
    • 按位与结果:111111110000,即 x = 4080

第 5 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 5
  3. 更新表达式x &= x - 1,即 x = 4080 & 4079
    • 4080 的二进制:111111110000
    • 4079 的二进制:111111101111
    • 按位与结果:111111100000,即 x = 4064

第 6 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 6
  3. 更新表达式x &= x - 1,即 x = 4064 & 4063
    • 4064 的二进制:111111100000
    • 4063 的二进制:111111011111
    • 按位与结果:111111000000,即 x = 4032

第 7 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 7
  3. 更新表达式x &= x - 1,即 x = 4032 & 4031
    • 4032 的二进制:111111000000
    • 4031 的二进制:111110111111
    • 按位与结果:111110000000,即 x = 3968

第 8 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 8
  3. 更新表达式x &= x - 1,即 x = 3968 & 3967
    • 3968 的二进制:111110000000
    • 3967 的二进制:111101111111
    • 按位与结果:111100000000,即 x = 3840

第 9 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 9
  3. 更新表达式x &= x - 1,即 x = 3840 & 3839
    • 3840 的二进制:111100000000
    • 3839 的二进制:111011111111
    • 按位与结果:111000000000,即 x = 3584

第 10 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 10
  3. 更新表达式x &= x - 1,即 x = 3584 & 3583
    • 3584 的二进制:111000000000
    • 3583 的二进制:110111111111
    • 按位与结果:110000000000,即 x = 3072

第 11 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 11
  3. 更新表达式x &= x - 1,即 x = 3072 & 3071
    • 3072 的二进制:110000000000
    • 3071 的二进制:101111111111
    • 按位与结果:100000000000,即 x = 2048

第 12 次循环:

  1. 条件判断x != 0 为真,进入循环。
  2. 循环体n++n 变为 12
  3. 更新表达式x &= x - 1,即 x = 2048 & 2047
    • 2048 的二进制:100000000000
    • 2047 的二进制:011111111111
    • 按位与结果:000000000000,即 x = 0

循环结束:

  • x = 0 时,x != 0 为假,退出循环。
  • 最终 n = 12

最终结果:

  • n = 12,即 4095 的二进制中有 121

http://www.lryc.cn/news/2398577.html

相关文章:

  • 实现Cursor + Pycharm 交互
  • C++标准模板库
  • dvwa6——Insecure CAPTCHA
  • 【机器学习及深度学习】机器学习模型的误差:偏差、方差及噪声
  • 【学习笔记】On the Biology of a Large Language Model
  • 飞腾D2000,麒麟系统V10,docker,ubuntu1804,小白入门喂饭级教程
  • 星野录(博客系统)测试报告
  • 使用 Java 实现一个简单且高效的任务调度框架
  • 2022—2025年:申博之路及硕士阶段总结
  • 项目执行中缺乏灵活应对机制,如何增强适应性?
  • Agentic Workflow是什么?Agentic Workflow会成为下一个AI风口吗?
  • 大模型模型推理的成本过高,如何进行量化或蒸馏优化
  • BUUCTF[极客大挑战 2019]EasySQL 1题解
  • Css样式中设置gap: 12px以后左右出现距离问题解析
  • MySQL问题:count(*)与count(1)有什么区别
  • 大模型 提示模板 设计
  • excel表格记账 : 操作单元格进行加减乘除 | Excel中Evaluate函数
  • 20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s
  • 如何合理设计缓存 Key的命名规范,以避免在共享 Redis 或跨服务场景下的冲突?
  • Trae CN IDE自动生成注释功能测试与效率提升全解析
  • 让AI弹琴作曲不再是梦:Python+深度学习玩转自动化音乐创作
  • C++概率论算法详解:理论基础与实践应用
  • ssh登录wsl2
  • 黑马Java面试笔记之 消息中间件篇(Kafka)
  • LeetCode - 234. 回文链表
  • PYTHON通过VOSK实现离线听写支持WINDOWSLinux_X86架构
  • nginx+tomcat动静分离、负载均衡
  • SQL进阶之旅 Day 13:CTE与递归查询技术
  • 【PmHub面试篇】Gateway全局过滤器统计接口调用耗时面试要点解析
  • neo4j 5.19.0两种基于向量进行相似度查询的方式