C++primer 3.5标准库bitset类型(5.3 位操作符)

本文详细介绍了C++中的bitset类型,包括如何定义和初始化bitset对象,如从unsigned值和string对象初始化,并探讨了bitset的位操作,如测试、访问和设置位。同时,解释了bitset中位的排列,从低阶位开始,高阶位结束,以及如何正确输出bitset的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重点

  • bitset是二进制位的有序集,里面的元素是0和1

  • 没有定义的时候,bitset< n >b,b里面的元素默认初始化为0,n 个0

  • 使用标准库bitset类型前要先声明 #include< bitset >

  • 在定义bitset时,要明确bitset含有多少位,需在尖括号内给出长度值。bitset< 32 > bitvec; bitvec对象含有32位,以0(低阶位)开始,31结束;

  • bitset初始化给出的长度值必须是常量表达式,必须是定义为整型字面值常量或是已经用常量值初始化的整型的const对象

  • 不管是unsigned 值还是string值初始化bitset对象,都是从右边向左边开始赋值,即从bitset的低阶位向高阶赋值,而且bitset低阶位下标最小,也就是说下标从右往左是越来越小的,这个不要搞错!!!(记住!!!)

  • 当用unsigned long 值作为bitset 对象的初始值时,该值将转化为二进制的位模式

  • 当用string对象初始化bitset对象时,string对象直接表示为位模

  • 当用string对象初始化时,需要注意:

================================================================================================

一、bitste对象的定义和初始化

1、bitset 对象的简介

  1. 有些程序要处理二进制位的有序集,每个位可能包含0(关)值或1(开)值。
  2. 位用来保存一组项或条件的yes/no信息(标志)的简洁方法。

  3. 使用标准库bitset类型前要先声明 #include< bitset >

2、bitset对象的定义和初始化

  • 类似于vector ,bitset类也是一种类模板,而与vector不同的是bitset类型对象的区别仅在其长度而不在其类型。

  • 在定义bitset时,要明确bitset含有多少位,需在尖括号内给出长度值。bitset< 32 > bitvec; bitvec对象含有32位,以0开始,31结束,0是低阶,31是高阶

  • bitset所谓的高阶位和低阶位
以0xffff为例,在机器内的存储方式为:
00000000000000001111111111111111,从高阶-->低阶。

(我不确定是存储方式是从低到高还是高阶到低阶,如果是低阶到高阶,那么把数字1放到前面来)
  • 给出的长度值必须是常量表达式,必须是定义为整型字面值常量或是已经用常量值初始化的整型的const对象

  • 和vector元素一样,bitset中的位是没有命名的,只能用位置来访问,这里是从0—31。

  • 以0位开始的位串是低阶位,以31位结束的位串是高阶位

  • 几种初始化方式

    • bitset< n >b;//n表示位数,每位都为0
    • bitset< n >b(u);//b是unsigned long型u 的一个副本
    • bitset< n >b(s);//b是string对象s中含有的位串的副本
    • bitset< n >b(s , pos, n);//b是s中从位置pos开始的n个位的副本

    • bitset< n >b(s , pos);//省略第三个参数表示的是从开始位置pos一直到string末尾的所有字符(这个要和上面那个区分开来)

2、用unsigned 值初始化bitset 对象

  • 当用unsigned long 值作为bitset 对象的初始值时,该值将转化为二进制的位模式。而bitset 对象中的位集作为这种位模式的副本。

  • 从右边向左边开始赋值,即从低阶位向高阶。

  • 如果bitset 类型长度大于unsigned long 值的二进制位数,则其余的高阶位置为0;

  • 如果bitset 类型长度小于unsigned long 值的二进制位数,则只使用unsigned 值中的低阶位,超过bitset 类型长度的高阶位将被丢弃。

问题:在bitset 对象中,位数是怎么排的,高阶和低阶是怎么样的??

这里写图片描述

在32位的unsigned long 的机器上,十六进制值0xffff表示为

这里写图片描述

//例子,在32位的unsigned long 的机器上,十六进制值0xffff表示为二进制位就是16个1 和16个0 (每个0xf可以表示为1111)。用0xffff初始化bitset对象。
int main()
{
bitset<16> bitvec1(0xffff);  
//bitset位数少于unsigned long的位数,所以,bitvec1的初始值高阶位被丢弃。bievec1 0---15设置为1

bitset<32> bitvec2(0xffff);  
//bievec2 0---15设置为1 ;16---31设置为0

bitset<128> bitvec3(0xffff);  
//bitset位数大于unsigned long的位数,所以,bitvec3的初始值高阶位被置为0。bievec1 32---127初始化为0

return 0;}

3、用string对象初始化bitset 对象

  • 当用string对象初始化bitset对象时,string对象直接表示为位模式。

  • 从string对象读入位集的顺序是从右到左

  • string对象和bitset对象之间是反向转化的:string对象的最右边字符(下标最大的)用来初始化bitset对象的低阶位(下标为0的)!!!!但是他们下标最大的那个字符都是在最右边的,这个不要搞错

  • 不一定要把string对象都作为bitset对象的初始值,可以只用某个子串作为初始值。

string strval("1100");
bitset<32> bitvec4(strval);
//bitvec4的位模式中第2和第3的位置为1,其余位置为0.

string str("1111111000000011001101");
bitset<32> bitvec5(str,5,4);//从str[5]开始的4个位,1100,bitvec5从3到0的二进制位置为1100,其余位置为0。

这里写图片描述

bitset <32> bitvec6(str,str.size()-4);
//省略第三个参数意味着取从开始位置一直到string末尾的所有字符。
//本例中,取出str末尾的四位来对bitvec6的低四位进行初始化。

这里写图片描述



//针对用string对bitset对象进行的初始化,我们首先把要拿来赋值的那段子串取出来(按照正常的顺序),再按他原本的顺序放到bitset对象里面,高阶位用0补。

4、输出bitset里面的元素

bitset<16> bitvec1(0xfffa);
bitset<32> bitvec2(0xfffa);
cout<<"bitvec1:"<<bitvec1<<endl;
cout<<"bitvec2:"<<bitvec2<<endl;

//输出:
//bitvec1:1111111111111010

 //bitvec2:00000000000000001111111111111010

输出并不是期待的顺序,而是相反的。这里还要说的是,bitset实现的<<操作符输出时,将会从bitset的高阶–>低阶输出(更自然)。

因此若用for循环从0开始输出就会是实际存储的顺序了。因为for循环从小的下标开始输出,也就是低阶开始输出。

#include <iostream>
#include<cstring> //使用下面的那些
#include<bitset>
using namespace std;
int main(){
bitset<16> bitvec1(0xfffa);
bitset<32> bitvec2(0xfffa);
cout<<"bitvec1:"<<bitvec1<<endl;   //输出的是bitvec1:1111111111111010
cout<<"bitvec2:"<<bitvec2<<endl;
//输出的是bitvec2:00000000000000001111111111111010

cout<<"bitvec1:";
   for(size_t bs1 = 0;bs1!=bitvec1.size();bs1++)
 {
   cout<<bitvec1[bs1];
 }
     cout<<endl;
//输出的是bitvec1:0101111111111111

 cout<<"bitvec2:";
   for(size_t bs1 = 0;bs1!=bitvec2.size();bs1++)
 {
     cout<<bitvec2[bs1];
 }
   cout<<endl;                              
  //输出的是bitvec2:01011111111111110000000000000000
return 0;
}


//输出的结果:

//没用for循环,从高阶到低阶输出
bitvec1:1111111111111010
bitvec2:00000000000000001111111111111010
//用for循环,从低阶到高阶输出
bitvec1:0101111111111111
bitvec2:01011111111111110000000000000000

这里写图片描述

二、bitste对象上的操作

1、测试整个bitset对象

  • 如果bitset对象中有一个或几个二进制位置为1,则 any操作返回true;
  • 如果要知道bitset 对象中1的个数,可以使用count操作,该操作返回置为1的二进制的个数;
    -

2、访问bitset对象中的位

  • 可以用下标操作符来读写某个索引位置的二进制位;
for(int index=0;index!=32;index+=2)
{bitbec[index]=1;}
  • 也可以使用set、test、和reset 操作来充值二进制位的值

3、对整个bitset 对象进行设置

  • set 和reset 分别用来对整个bitset 对象的所有二进制位全置为1和0.
  • flip 操作可以对bitset 对象的所有位或个别位取反
bitvec.reset();//所有比特全设为0
bitvec.set();//所有比特全设为1

bitvec.flip(0);//第一个比特位取反
bitvec[0].flip();
bitvec.flip();//全部比特位取反
4、获取bitset 对象的值

17.1节后面再讨论

5、输出二进制位
//可以用输出操作符输出bitset对象中的位模式

bitset<32>bitvec2(0xffff);// 从0到15设为1,从16到31设为0
cout<<“bitvec2:”<<bitvec2<<endl;

//输出结果
//bitvec2:00000000000000001111111111111111
//有没有发现输出来的顺序是反的,就是从高阶位开始输出
6、使用位操作符

5.3 节将介绍这些操作符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值