C++primer 3.5標準庫bitset類型(5.3 位操作符)

重點

  • 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 節將介紹這些操作符

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章