C++_系列自学课程_第_6_课_bitset集_《C++ Primer 第四版》
在C语言中要对一个整数的某一个位进行操作需要用到很多的技巧。这种情况在C++里面通过标准库提供的一个抽象数据类型
bitset得到了改善。
一、标准库bitset类型
1、bitset的作用
bitset可以看成bit的集合,可以单独的访问集合中的某一位,访问的结果可以作为逻辑的判断的条件。使用bitset的时候可以
不关心这些bit的存储方式,而通过bitset类型提供的一套接口进行操作。
和string和vector一样,要使用bitset类型,需要报备,如下所示:
#include <bitset> //包含相关的头文件
#using std::bitset; //声明使用相应的命名空间的名字
2、bitset的定义
在定义bitset对象的时候,需要指出bitset对象要存储多少bit, 这通过在bitset后面的<>中设置,如下所示:
bitset<n> bitTset; //定义一个bitset对象bitTest, n为对象可以存储的bit的位数
Exp:
bitset<16> b16Test; // 定义存储16bit 的 bitset的对象
bitset<32> b32Test; //定义存储32bit的bitset对象
要点:
bitset<n> bitObj; 定义的时候n的值必须是一个整型字面值或者用整型字面值初始化的const对象,不能是变量,这一点
必须要注意。
Exp:
int main()
{
bitset<> bitObj(); cout<<bitObj<<endl; return ;
}
执行结果如下所示:
[root@localhost cpp_src]# g++ test.cpp
[root@localhost cpp_src]# ./a.out
3、bitset类的初始化
bitset提供了多种初始化的方法,如下所示:
bitset<n> bitsetObj1; //初始化bitset对象bitsetObj1的所有的bit为0;
bitset<n> bitsetObj2(u); //利用无符号数整型数 u 来初始化bitset对象bitsetObj2;
bitset<n> bitsetObj3(string); //利用string对象初始化bitset对象bitsetObj3;
bitset<n> bitsetObj4(string, pos, m); //利用string对象来初始化从pos位开始的m位
要点:
利用无符号数u和string对象初始化的时候,可能会存在长度不匹配的情况。而且string对象是一个0、1组成的字符序列。
利用无符号数初始化的时候会先将无符号数转换成二进制格式然后存储到bitset对象中; 利用string对象初始化的时候也会先将string
对象转换为二进制格式然后存储到bitset对象中。
Exp: 初始化bitset对象
int main()
{
string str="";
bitset<> bitObj1; //16个bit全为0
bitset<> bitObj2(0xffff); //32个bit, 高16bit的全是0, 低16bit全是1
bitset<> bitObj3(str); //这个需要在下面细说一下 cout<<sizeof(0xffff)<<endl; return ;
}
上面的初始化中需要注意string对象的初始化的时候,不能用字符串字面值来初始化。
对于 :
string str="1111_1010_1101"; //这利用 _ 分隔是为了更好的查看
bitset<8> bitObj3(str);
bitset<32> bitObj4(str);
这样初始化后 bitObj3的bit的存放的结果如下所示: 11111010;
bitObj4的结果如下: 00000000000000000000111110101101
可以发现规律: 当string对象的长度大于bitset对象容量的时候,会将string的后半部分截断, 而保留string对象中下标相对较小
的字符序列。
当string对象的长度小于bitset对象的容量的时候,就将string对象全部进行转换,并且将string对象进行"平行移动"到bitset对象的
低位部分, 剩下的bitset不足的高位部分用0补齐。
Exp:
int main()
{
string str="";
bitset<> bitObj1;
bitset<> bitObj2(0xffff);
bitset<> bitObj3(str);
bitset<> bitObj4(str); cout<<bitObj3<<endl;
cout<<bitObj4<<endl;
cout<<sizeof(0xffff)<<endl; return ;
}
执行结果为:
[root@localhost cpp_src]# g++ bitset_init.cpp
[root@localhost cpp_src]# ./a.out
Exp: 利用部分的string的字符序列初始化bitset对象
int main()
{
string str="";
bitset<> bitObj1(str,,);
bitset<> bitObj2(str,str.size()-); cout<<bitObj1<<endl;
cout<<bitObj2<<endl;
cout<<str.size()<<endl; return ;
}
执行结果如下所示:
[root@localhost cpp_src]# ./a.out
下面解释一下这个结果:
string str("11_1111_1000_0000_1100_1101") ; //
bitset<32> bitObj1(str, 5, 4); 这个初始化的意思就是从str对象中的str[5]开始,取4个字符来初始化bitObj1对象。因为取出来的
字符长度小于32bit,因此遵循前面说的string长度小于bitset对象长度的赋值方法。
bitset<32> bitObj2(str, str.size() - 4); 这里只有两个参数,最后一个参数没有,就表示从str.size()-4开始取字符序列,一直取字
符到string对象的最后一个字符,然后进行转换, 而且转换过程遵循前面说过的关于string对象和bitset对象长度的赋值规则。
因此得到了上面的运行结果。
其实后面这两种的初始化主要需要注意的是如何取字符序列,字符序列取出来后,就把取出来的字符序列当成一个新的string对象进行初始
化就可以啦。
4、bitset类提供的操作
和其他的标准库类一样,bitset也提供了很多的操作,主要有如下一些:
bitset<n> bitObj;
bitObj.any( ); 返回bitObj对象中是否存在已经设为 1 的bit
bitObj.none(); 返回bitObj不存在为1的二进制bit吗, 就是测试是否所有的bit全是0, 全是0时返回true
bitObj.count(); 返回bitObj中1的位数
bitObj.size(); 返回bitObj对象的bit个数
bitObj[pos] ; 返回bitObj的pos位置处的二进制bit的值
bitObj.set(); 设置为1;
bitObj.set(pos); 设置pos处的bit为1;
bitObj.reset(); 设置全为0;
bitObj.reset(pos); 设置pos位置为0
bitObj.flip(); 所有的bit取反;
bitObj.flip(pos); 将pos位置处的bit取反。
bitObj.to_ulong() 将bitObj转换为unsigned long int类型
os<<b; 将b中的bitset集输出到os流。
int main()
{
bitset<> bitObj(); cout<<bitObj<<endl;
cout<<"The size of bitObj is:"<<bitObj.size()<<endl;
cout<<"bitObj.to_ulong() is:"<<bitObj.to_ulong()<<endl; cout<<"bitObj[3] is:"<<bitObj[]<<endl; if(bitObj.any())
cout<<"bitObj has some bit == 1"<<endl;
else
cout<<"bitObj has no bit == 1"<<endl; if(bitObj.none())
cout<<"bitObj all bit is 0."<<endl;
else
cout<<"bitObj has some bit == 1"<<endl; bitObj.set();
cout<<"after bit.set() bitObj is:"<<bitObj<<endl;
bitObj.reset();
cout<<"after bit.reset(3),the bitObj is:"<<bitObj<<endl; bitObj.reset();
cout<<"after bitObj.reset() bitObj is:"<<bitObj<<endl;
bitObj.set();
cout<<"after bitObj.set(4),bitObj is:"<<bitObj<<endl; cout<<"bitObj.flip() is:"<<bitObj.flip()<<endl; cout<<"bitObj is"<<bitObj<<endl;
bitObj.flip();
cout<<"after bitObj.flip(1),bitObj is:"<<bitObj<<endl; return ;
}
执行结果如下所示:
[root@localhost cpp_src]# ./a.out The size of bitObj is:
bitObj.to_ulong() is:
bitObj[] is:
bitObj has some bit ==
bitObj has some bit ==
after bit.set() bitObj is:
after bit.reset(),the bitObj is:
after bitObj.reset() bitObj is:
after bitObj.set(),bitObj is:
bitObj.flip() is:
bitObj is01111
after bitObj.flip(),bitObj is:
[root@localhost cpp_src]#
通过上面的实例可以知道两个特点需要特别的注意:
b.set(n)、b.reset(n)、b.flip(n); 这个n是从0开始计算的, 而且是从最低位开始计算的。
下面还有一个例子:
int main()
{
bitset<> bitObj(); cout<<bitObj<<endl;
cout<<bitObj[]<<endl;
cout<<bitObj[]<<endl;
cout<<bitObj[]<<endl;
cout<<bitObj[]<<endl;
cout<<bitObj[]<<endl; return ;
}
执行结果为:
[root@localhost cpp_src]# g++ test.cpp
[root@localhost cpp_src]# ./a.out
从上面的结果看,bitset的下标操作为从0开始计数,而且是从最低为开始计数的, 就是说 bitObj[0] 表示的bitset的最低位。
这次就说的这里,接下来将是与C语言相关的数组和指针的内容啦,待续.........
C++_系列自学课程_第_6_课_bitset集_《C++ Primer 第四版》的更多相关文章
- C++_系列自学课程_第_7_课_数组_《C++ Primer 第四版》
说到数组,大家应该都很熟悉,在C.Pascal.Java等语言中,都有数组的概念.在C++中也提供了对数组的支持.数组简单来说就是一堆相同 数据类型对象的集合. 这里要把握住两个要点: 相同的数据类型 ...
- C++_系列自学课程_第_5_课_vector容器_《C++ Primer 第四版》
再一次遇到 vector 这个单词; 每一次见到这个单词都感觉这个单词非常的 "高大上"; 数字遇到vector马上就可以360度旋转: 当 "电" 遇到vec ...
- C++_系列自学课程_第_3_课_变量和基本类型_《C++ Primer 第四版》
最近复习C++相关内容,决定在这里记录自己复习的过程. 以前写过部分文字,但是没有坚持连续写,因此学完后 基本又忘光啦,主要是没有实践,这一次决定自学完后,在这里在复习一遍增强自己的记忆和理解程度. ...
- C++_系列自学课程_第_12_课_结构体
#include <iostream> #include <string> using namespace std; struct CDAccount { double bal ...
- C++_系列自学课程_第_12_课_语句_《C++ Primer 第四版》
前面的文章说完了表达式和类型转换的部分内容,在我参考的书里面,接下来讨论的是各种语句,包括:顺序语句.声明语句.复合语句(块语句).语句作用域 .if语句.while语句.for语句.do...whi ...
- C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》
上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...
- C++_系列自学课程_第_10_课_表达式_《C++ Primer 第四版》
程序设计语言中大部分程序都在进行表达式的求值操作, 例如求两个数的和,求一个表达式的逻辑结果,或者通过输入输出表达式语句进行输入和输出. 这里我们对表达式进行讨论. 一.表达式 1.表达式 表达式由一 ...
- C++_系列自学课程_第_9_课_C语言风格字符串_《C++ Primer 第四版》
前面说了写关于数组和指针的内容,这次在这里讨论一下字符串,讨论一下C语言风格的字符串. 在C语言里面我们利用字符数组来对字符串进行处理, 在C++里面我们前面说过一种类类型string可以对字符串进行 ...
- C++_系列自学课程_第_8_课_指针和引用_《C++ Primer 第四版》
C语言最富有迷幻色彩的部分当属指针部分,无论是指针的定义还是指针的意义都可算是C语言中最复杂的内容.指针不但提供给了程序员直接操作硬件部分的操作接口,还提供给了程序员更多灵活的用法.C++继承这一高效 ...
随机推荐
- MySQL 复制表结构
200 ? "200px" : this.width)!important;} --> 介绍 有时候我们需要原封不动的复制一张表的表结构来生成一张新表,MYSQL提供了两种便 ...
- SQL Server 复制订阅
标签:SQL SERVER/MSSQL SERVER/数据库/DBA/高性能解决方案/高可用 概述 配置复制就没有数据库镜像和AlwaysOn的要求那么高,只需要两台服务器能通过TCP进行通讯即可,两 ...
- Opengl中矩阵和perspective/ortho的相互转换
Opengl中矩阵和perspective/ortho的相互转换 定义矩阵 Opengl变换需要用四维矩阵.我们来定义这样的矩阵. +BIT祝威+悄悄在此留下版了个权的信息说: 四维向量 首先,我们定 ...
- ASP.NET Web API的Controller是如何被创建的?
Web API调用请求的目标是定义在某个HttpController类型中的某个Action方法,所以消息处理管道最终需要激活目标HttpController对象.调用请求的URI会携带目标HttpC ...
- 优化MySchool数据库设计之【巅峰对决】
优化MySchool数据库设计 之独孤九剑 船舶停靠在港湾是很安全的,但这不是造船的目的 By:北大青鸟五道口原玉明老师 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识 ...
- C语言 · 特殊回文数
问题描述 123321是一个非常特殊的数,它从左边读和从右边读是一样的. 输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n . 输入格式 输入一行,包含一个正整数n. 输 ...
- c#设计模式-适配器模式
一. 适配器(Adapter)模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作. 名称由来 这很像变压器(Adapter),变压 ...
- SQL Server 创建数据库邮件
一. 背景 数据库发邮件通知数据库的运行状态(状态可以通过JOB形式获取)和信息,达到预警的效果. 二. 基础知识 msdb系统数据库保存有关Job,Database Mail,Nodifyicati ...
- jQuery 2.0.3 源码分析Sizzle引擎 - 高效查询
为什么Sizzle很高效? 首先,从处理流程上理解,它总是先使用最高效的原生方法来做处理 HTML文档一共有这么四个API: getElementById 上下文只能是HTML文档 浏览器支持情况:I ...
- supportRequestWindowFeature与requestWindowFeature
在Activity中去掉标题栏只需要在onCreate()中在setContentView前使用requestWindowFeature(). 在AppCompatActivity中去掉标题栏只需要在 ...