探究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的个数
  3. 使用 for 循环,初始条件为 n = 0
  4. 循环条件为 x != 0
  5. 每次循环,x 更新为 x &= x - 1,这一步会去掉 x 的二进制表示中最低位的 1
  6. 每次循环,n 增加 1,表示找到一个 1
  7. 输出:循环结束后,输出 n,即 x 的二进制表示中 1 的个数。

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

初始状态:

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

  • 3 的二进制表示为 11
  • 运行步骤:

    1. 第一次循环:

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

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

    12. 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. 初始化

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

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

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

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

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

    变量变化

    循环次数 x 的二进制 x 的十进制 n 的值
    初始化 0b11 3 0
    第一次 0b10 2 1
    第二次 0b00 0 2

    最终输出

    程序最终输出 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
    4. 4095 的二进制:111111111111
    5. 4094 的二进制:111111111110
    6. 按位与结果:111111111110,即 x = 4094

    第 2 次循环:

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

    第 3 次循环:

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

    第 4 次循环:

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

    第 5 次循环:

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

    第 6 次循环:

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

    第 7 次循环:

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

    第 8 次循环:

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

    第 9 次循环:

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

    第 10 次循环:

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

    第 11 次循环:

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

    第 12 次循环:

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

    循环结束:

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

  • 最终结果:

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

  • 作者:babyai997

    物联沃分享整理
    物联沃-IOTWORD物联网 » 探究ccf中学生计算机程序设计入门篇P164页test(1)-2:输入数字统计其二进制形式中1的个数

    发表回复