• 把《c++ primer》读薄(3-3 标准库bitset类型)


    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正。

    //开头
    #include <bitset>
    using std::bitset;

    问题1、标准库bitset类型(模版)

    需要处理二进制位的时候,可以使用c++标准库提供的bitset类型,它也是类模版,类似vectro容器,唯一不同的是,bitset类型需要说明长度,使用常量表达式给出的整型字面值或者已经初始化的cosnt对象。

        bitset<32> bit;//从0到31位算的,bit的32位每位初始化为0

    使用无符号的值初始化bitset对象,该值被初始化为二进制序列,如果无符号值长度小于bitset对象,那么就把高阶位截掉

        bitset<16> bit1(0xffff);//0-15位都是1
        bitset<32> bit2(0xffff);//0-15位是1,16-31是0
        bitset<128> bit3(0xffff);//32-127位都是0
        bitset<8> bit0(0xffff);//高位被截去

    问题2、使用string对象初始化bitset对象需要注意的问题

    使用string对象初始化bitset对象的时候,直接初始化为二进制序列,从string字符串对象的右边开始读取!!

     1     string str1("1000");
     2     //bit1对象的0-3位为0001,其余高位为0
     3     bitset<32> bit1(str1);
     4     //一定注意起来,string对象和bitset对象的转换是反向的!也就是string对象的下标最大的(右边)开始读取到bitset对象里面
     5 
     6     //还可以这样初始化
     7     string str2("1111111100000000");
     8     //从str2字符串对象的第5位开始的4位,初始化bit2对象
     9     //即:1100
    10     //从右边读取(string对象的高位读取,那么就是0011存储在bit2对象里的0-3位)
    11     bitset<32> bit2(str2, 5, 4);//其他二进制位数都是0
    12 
    13     //如果省略第三个参数,就是从指定位置到末尾
    14     string str3("10001000");
    15     //从str3字符串对象的第2位开始到末尾
    16     //001000
    17     bitset<32> bit3(str3, 2);//存储在bit3对象里0-5位的是000100

    问题3、bitset对象的常见操作

        bitset<32> b(0x0000);
        //如果b里的位序含有1,那么返回true
        if (b.any())
        {
            cout << "执行!" << endl;//没有被执行,返回的是false
        }

    测出b对象里的1的个数

    cout << b.count() << endl;//0

    注意,count函数返回的值是size_t类型,定义在头文件cstddef中,c里是stddef.h,size_t是一个无符号的和机器无关的整型。类似无符号int类型

    size_t num = b.count();//ok

    下面这样虽然不报错,但是以前说过类似的问题,不建议使用,这里就看成是错的

    //int num2 = b.count();

    类似容器vector或者string类型,bitset也有求长度的函数size()

        cout << b.size() << endl;//打印32,说明求的是实际定义的时候规定的长度
        //同样返回的是size_t类型
        size_t num1 = b.size();

    //访问bitset对象里的位,大同小异,类似其他容器或者标准库,数组的下标操作

        bitset<32> bit;//自动默认初始化为32个0
        //循环,这里的i使用int类型定义,因为这里的bitset对象的长度是使用的32,也就是int类型定义的
        for (int i = 0; i != 32; i++)
        {
            bit[i] = 1;//32位。0-31全部初始化为1
        }

    //测试bitset对象某一位是不是1

        bitset<32> bit1(0x1000);
        if (bit.test(0))
        {
            cout << "执行" << endl;//执行!说明第一位是1
        }

    //或者直接使用下标操作的返回值

        cout << bit1[1] << endl;//打印0,对应false
        //那么自然可以直接拿来做bool判断了,因为它无非就是返回0或者1啊

    //把所有二进制位数都设置为1

        bit1.set();
        cout << bit1.count() << endl;//32

    //只是把第1位设置为1

        bitset<32> bit2(0x0000);
        bit2.set(0);
        cout << bit2.count() << endl;//1
        cout << bit2.any() << endl;//1

    //把所有二进制位都设置为0

        bit2.reset();
        cout << bit2.count() << endl;//0

    //同样,只是设置某位为0

        bitset<32> bit3(0x1111);
        cout << bit3.count() << endl;//4
        bit3.reset(0);
        cout << bit3.count() << endl;//3

    //取反操作

        bitset<32> bit4(0x0000);
        cout << bit4.count() << endl;//0
        bit4.flip();//对所有的位数按位取反
        cout << bit4.count() << endl;//32

    //同样,类似操作,只对某一位取反

        bit4.flip(0);//对第一位取反

    //当且仅当,bitset对象的长度小于或者等于无符号long整型的变量时,可以使用如下函数

        unsigned long ln = bit4.to_ulong();//ok
        //否则报错,出现异常

    问题4、一定注意,bitset对象的下标问题,是从右边开始的!

        //直接输出bitset对象
        bitset<16> bit5(0xffff);
        cout << bit5 << endl;

        bitset<32> bit(0xffff);
        cout << bit << endl;

    一定注意,下标从右边开始是0-31,不是传统的左边开始了

    从右边开始0-15为1,其余高位0填充。

    问题5、如题,bitset<32> bit(1010101),初始化bit的结果是什么?

        bitset<32> bit(1010101);
        //注意,这样初始化,默认1010101是十进制!先转换为二进制:
        //000000000000011110110100110110101
        //然后初始化bit对象为二进制序列

    千万不要想当然的认为,这是写1010101就是二进制,其实默认的是十进制形式

    小结:

    c++标准库定义的数组和指针等属于低级的抽象数据类型,而标准库的容器比如vector,还有标准库bitset类模版,string类型等,都是高级的抽象数据类型!其中,string类型提供了变长的字符串存储操作,vector容器提供了对某总类型的对象的存储操作。

    还有学到的迭代器,提供了间接访问容器内对象的方法(可以代替下标)。比如访问和遍历vector容器内对象或者string类型的元素。

    记住,优秀的c++程序员,应该习惯使用高级抽象数据类型,尽量避免使用低级的数组还有指针。除非是强调程序运行的速度的模块,那样就应该使用低级的复合数据类型,指针或者数组。

    欢迎关注

    dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!

  • 相关阅读:
    WinForm常用代码
    XML编程与应用-读取XML
    基础SQL语句
    WPF基础——继承
    wpf控件
    手机网页支付
    Application_Start 多次启动问题
    更改Outlook 2013中Exchange数据文件存放路径
    MySql双机热备份
    图片轮播(Jquery)
  • 原文地址:https://www.cnblogs.com/kubixuesheng/p/4145203.html
Copyright © 2020-2023  润新知