zoukankan      html  css  js  c++  java
  • 【看书】while(m)m&=m-1,s++;的解释

    此讨论是关于【NYOJ】[100]1的个数的补充说明
    对于这一题标程给的这一句代码 比较难理解

    所以分开来解析

    逗号表达式

    while(m)m&=m-1,s++;可以写为:

    while(m)
        m&=m-1,s++;

    首先是”,”所代表的意思
    此处是作为 逗号运算符
    关于逗号运算符:

    逗号运算符可以把两个以上(包含两个)的表达式连接成一个表达式,称为逗号表达式。

    逗号运算符的优先级是所有运算符中级别最低的,通常配合 for 循环使用。

    所以常用的for(i=0,n=1;i<10;i++)
    这种,这个i=0,n=1便是逗号表达式

    对于a + b, c = b, c++这个式子

    逗号表达式最右边的子表达式的值即为逗号表达式的值。上例中,c++ 的值(c 自增之前的值)即为该表达式的值。

    逗号运算符保证左边的子表达式运算结束后才进行右边的子表达式的运算。也就是说,逗号运算符是一个序列点,其左边所有副作用都结束后,才对其右边的子表达式进行运算。因此,上例中,c 得到 b 的值后,才进行自增运算。

    验证程序:

    #include<stdio.h>
    int main() {
        int x,a;
        x=(a=3,6*3);
        printf("a=%d,x=%d
    ",a,x);
        x=a=3,6*a;
        printf("a=%d,x=%d
    ",a,x);
        return 0;
    }
    

    所以while(m)m&=m-1,s++;可看作是两条循环语句

    m&=m-1;
    s++;

    位运算

    s++ 很好理解
    那么m&=m-1;的解释又应该怎么说呢

    &在这里应是按位与
    也就是二进制的数每个位,两个数都是 1这个位才是1

    常用的
    if(a&1) 就相当于如果a是奇数
    因为如果a是奇数 那么最后一位就是1
    a&1 结果也应该是1
    如果是偶数 那么a&1==0

    在这里 m&=m-1 =>m=m&m-1
    为什么这样写能计算出1的个数呢

    举例
    5的二进制 101
    则运算过程为
    100&101==100 =>s==1
    100&011==0 =>s==2

    分析
    m&m-1 使得如果最后一位是1
    那么结果便相当于去除了最后以为的1并把结果+1
    如果最后一位是0
    那么其前一个1位在运算后会变成0 并结果+1
    而且使得其自身还是为0

    所以通过这种方式一次一次把1位拨成0位
    然后记录次数
    从而可以得出数字二进制有几个1

    也是二进制运算很奇妙的一种体现

    参考文章:
    《C语言程序设计——贾宗璞 许合利》
    c语言中逗号运算符的功能和使用方法_百度知道
    位运算_百度百科

  • 相关阅读:
    (字典树)Revenge of Fibonacci -- HDU -- 4099
    (字符串 KMP)Blue Jeans -- POJ -- 3080:
    (广搜)聪明的打字员 -- POJ --1184
    (线段树 点更新 区间求和)lightoj1112
    Jquery弹窗插件Lhgdialog的用法
    SQL Server数据库大型应用解决方案总结
    C# 使用XmlDocument类对XML文档进行操作
    反射实例【转】
    如何使用dynamic
    [C#]DataTable常用操作总结
  • 原文地址:https://www.cnblogs.com/BoilTask/p/12569853.html
Copyright © 2011-2022 走看看