在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<5> bitObj(5); cout<<bitObj<<endl; return 0; }
執行結果如下所示:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out 00101
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="111110101101"; bitset<16> bitObj1; //16個bit全為0 bitset<32> bitObj2(0xffff); //32個bit, 高16bit的全是0, 低16bit全是1 bitset<8> bitObj3(str); //這個需要在下面細說一下 cout<<sizeof(0xffff)<<endl; return 0; }
上面的初始化中需要注意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="111110101101"; bitset<16> bitObj1; bitset<32> bitObj2(0xffff); bitset<8> bitObj3(str); bitset<32> bitObj4(str); cout<<bitObj3<<endl; cout<<bitObj4<<endl; cout<<sizeof(0xffff)<<endl; return 0; }
執行結果為:
[root@localhost cpp_src]# g++ bitset_init.cpp [root@localhost cpp_src]# ./a.out 11111010 00000000000000000000111110101101 4
Exp: 利用部分的string的字符序列初始化bitset對象
int main() { string str="1111111000000011001101"; bitset<32> bitObj1(str,5,4); bitset<32> bitObj2(str,str.size()-4); cout<<bitObj1<<endl; cout<<bitObj2<<endl; cout<<str.size()<<endl; return 0; }
執行結果如下所示:
[root@localhost cpp_src]# ./a.out 00000000000000000000000000001100 00000000000000000000000000001101 22
下面解釋一下這個結果:
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<5> bitObj(5); 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[3]<<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(3); cout<<"after bit.reset(3),the bitObj is:"<<bitObj<<endl; bitObj.reset(); cout<<"after bitObj.reset() bitObj is:"<<bitObj<<endl; bitObj.set(4); cout<<"after bitObj.set(4),bitObj is:"<<bitObj<<endl; cout<<"bitObj.flip() is:"<<bitObj.flip()<<endl; cout<<"bitObj is"<<bitObj<<endl; bitObj.flip(1); cout<<"after bitObj.flip(1),bitObj is:"<<bitObj<<endl; return 0; }
執行結果如下所示:
[root@localhost cpp_src]# ./a.out 00101 The size of bitObj is:5 bitObj.to_ulong() is:5 bitObj[3] is:0 bitObj has some bit == 1 bitObj has some bit == 1 after bit.set() bitObj is:11111 after bit.reset(3),the bitObj is:10111 after bitObj.reset() bitObj is:00000 after bitObj.set(4),bitObj is:10000 bitObj.flip() is:01111 bitObj is01111 after bitObj.flip(1),bitObj is:01101 [root@localhost cpp_src]#
通過上面的實例可以知道兩個特點需要特別的注意:
b.set(n)、b.reset(n)、b.flip(n); 這個n是從0開始計算的, 而且是從最低位開始計算的。
下面還有一個例子:
int main() { bitset<5> bitObj(12); cout<<bitObj<<endl; cout<<bitObj[0]<<endl; cout<<bitObj[1]<<endl; cout<<bitObj[2]<<endl; cout<<bitObj[3]<<endl; cout<<bitObj[4]<<endl; return 0; }
執行結果為:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out 01100 0 0 1 1 0
從上面的結果看,bitset的下標操作為從0開始計數,而且是從最低為開始計數的, 就是說 bitObj[0] 表示的bitset的最低位。
這次就說的這裡,接下來將是與C語言相關的數組和指針的內容啦,待續.........