C++_系列自学课程_第_6_课_bitset集_《C++ Primer 第四版》

时间:2023-03-09 14:21:31
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语言相关的数组和指针的内容啦,待续.........