顧名思義,按位運算符允許按照位來操作整型變量。可以把按位運算符應(yīng)用于任意signed和unsigned整型,包括char類型。但是,它們通常應(yīng)用于不帶符號的整型。
這些運算符的一個常見應(yīng)用是在整型變量中使用單個的位存儲信息。例如標(biāo)記,它用于描述二進制狀態(tài)指示符。可以使用一個位來描述有兩個狀態(tài)的值:開或關(guān)、男或女,真或假。
也可以使用按位運算符處理存儲在一個變量中的幾個信息項。例如,顏色值常常記錄為三個八位值,分別存儲顏色中紅、綠和藍(lán)的強度。這些常常保存到四字
節(jié)變量中的三個字節(jié)。第四個字節(jié)也不會浪費,包含表示顏色透明度的值。顯然,要處理各個顏色成分,需要從變量中分離出各個字節(jié),按位運算符就可以做到這一
點。
再看另外一個例子,假定需要記錄字體的信息,那么,只要存儲每種字體的樣式和字號,以及字體是黑體還是斜體,就可以把這些信息都存儲在一個二字節(jié)的整型變量中,如圖3-1所示。

圖3-1 把字體數(shù)據(jù)存儲在2個字節(jié)中
可以使用一位來記錄字體是否為斜體——
1表示斜體,0表示一般。同樣,用另一位來指定字體是否為黑體。使用一個字節(jié)可以從多達(dá)256種不同的樣式中選擇一個,再用另外5位記錄最多32磅的字
號。因此,在一個16位的字中,可以記錄四個不同的數(shù)據(jù)項。按位運算符提供了訪問和修改整數(shù)中單個位和一組位的便利方式,能方便地組合和分解一個16位的
字。
3.3.1 移位運算符
移位運算符可以把整型變量中的內(nèi)容向左或向右移動指定的位數(shù)。移位運算符和其他按位運算符一起使用,可以獲得前面描述的結(jié)果。>>運算符把位向右移動,<<運算符把位向左移動,移出變量兩端的位被舍棄。
所有的按位操作都可以處理任何類型的整數(shù),但本章的例子使用16位的變量,使例子較為簡單。用下面的語句聲明并初始化一個變量number:
unsigned short number=16387U;
如第2章所述,不帶符號的字面量應(yīng)在數(shù)字的最后添加字母U或u。
在下面的語句中,對這個變量的內(nèi)容進行移位,并存儲結(jié)果:
unsigned short result = number <<2; //Shift left two bit positions
移位運算符的左操作數(shù)是要移位的值,右操作數(shù)指定要移動的位數(shù)。圖3-2列出了該操作的過程。

圖3-2 移位運算
從圖3-2可以看出,把數(shù)值16387向左移動兩位,得到數(shù)值12。數(shù)值的這種劇烈變化是舍棄高位數(shù)字的結(jié)果。
把數(shù)值向右移動,可以使用下面的語句:
result = number >>2; //Shift right two bit positions
把數(shù)值16387向右移動兩位,得到數(shù)值4096。向右移動兩位相當(dāng)于使該數(shù)值除以4。
只要沒有舍棄位,向左移動n位就相當(dāng)于把該數(shù)值乘以2的n次方。換言之,就等于把該數(shù)值乘以2n。同樣,向右移動n位就相當(dāng)
于把該數(shù)值除以2的n次方。但要注意,變量number向左移位時,如果舍棄了重要的位,結(jié)果就不是我們希望的那樣了。可是,這與乘法運算并沒有不同。如
果把2字節(jié)的數(shù)值乘以4,就會得到相同的結(jié)果,所以向左移位和相乘仍是等價的。出現(xiàn)問題的原因是相乘的結(jié)果超出了2字節(jié)整數(shù)的取值范圍。
如果需要修改原來的值,可以使用op= 賦值運算符。在這種情況下,可以使用>>=或<<=運算符。例如:
number >>= 2; // Shift contents of number two positions to the right
這等價于:
number =number >> 2; // Shift contents of number two positions to the right
這些移位運算符跟前面用于輸入輸出的插入和提取運算符有可能搞混。從編譯器的角度來看,其含義一般可以從上下文中判斷出來。否則,編譯器就會生成一個消息,但用戶需要非常小心。例如,如果輸出變量number向左移動兩位的結(jié)果,就應(yīng)編寫下面的代碼:
cout << (number << 2);
其中,括號是必不可少的。沒有括號,編譯器就會把移位運算符解釋為流插入運算符,從而得不到想要的結(jié)果。
按位移動帶符號的整數(shù)
可以把移位運算符應(yīng)用于帶符號和不帶符號的整型數(shù)。但是,向右移位運算符在帶符號整數(shù)類型的操作隨系統(tǒng)的不同而不同,這取決于編譯器的實現(xiàn)。在一些情況下,向右移位運算符會在左邊空出來的位上填充0。在其他情況下,符號位向右移動,在左邊空出來的位上填充1。
移動符號位的原因是為了保持向右移位和除法運算的一致性。可以用char類型的變量來說明這一點,解釋其工作原理。假定把value定義為char類型,其初始值為–104(十進制):
signed char value=–104;
其二進制表示為10011000。使用下面的操作把它向右移動兩位:
value >>= 2; //Result 11100110
注釋中顯示了其二進制結(jié)果。右邊溢出了兩個0,因為符號位是1,就在左邊空出來的位上填充1。該結(jié)果的十進制表示是–26,這正好是value的值除以4的結(jié)果。當(dāng)然,對于不帶符號的整數(shù)類型的操作,符號位不移動,在左邊空出來的位上填充0。
前面說過,在向右移位負(fù)整數(shù)時,其操作是已定義好的,所以實現(xiàn)該操作時不一定要依賴它。因為在大多數(shù)情況下,使用這些運算符是為了進行按位操作,此時維護位模式的完整性是非常重要的。所以,應(yīng)總是使用不帶符號的整數(shù),以確保避免高階位的移位。
3.3.2 位模式下的邏輯運算
修改整數(shù)值中的位時,可以使用4個按位運算符,如表3-1所示。
表3-1 按位運算符
運 算 符
|
說 明
|
~
|
這是按位求反運算符。它是一個一元運算符,可以反轉(zhuǎn)操作數(shù)中的位,即1變成0,0變成1
|
&
|
這是按位與運算符,它對操作數(shù)中相應(yīng)的位進行與運算。如果相應(yīng)的位都是1,結(jié)果位就是1,否則就是0
|
^
|
這是按位異或運算符,它對操作數(shù)中相應(yīng)的位進行異或運算。如果相應(yīng)的位各不相同,例如一個位是1,另一個位是0,結(jié)果位就是1。如果相應(yīng)的位相同,結(jié)果位就是0
|
|
|
這是按位或運算符,它對操作數(shù)中相應(yīng)的位進行或運算。如果兩個對應(yīng)的位中有一個是1,結(jié)果位就是1。如果兩個位都是0,結(jié)果就是0
|
表3-1中的運算符按照其優(yōu)先級排列,在這個集合中,按位求反運算符的優(yōu)先級最高,按位或運算符的優(yōu)先級最低。在附錄D的運算符優(yōu)先級表中,按位移動運算符<<和>>具有相同的優(yōu)先級,它們位于~運算符的下面,&運算符的上面。
如果以前沒有見過這些運算符,就會問“這非常有趣,但這是為什么?”。下面就將它們用于實踐。
1. 使用按位與運算符
按位與運算符一般用于選擇整數(shù)值中特定的一個位或一組位。為了說明這句話的含義,下面再次使用本節(jié)開頭的例子,利用一個16位整數(shù)存儲字體的特性。
假定聲明并初始化一個變量,指定一種12磅字號、斜體、樣式為6的字體。實際上,就是圖3-1中的字體。樣式的二進制值是00000110,斜體位
是1,黑體位是0,字號是01100。還有一個沒有使用的位,需要把font變量的值初始化為二進制數(shù)0000 0110 0100 1100。
由于4位二進制數(shù)對應(yīng)于一個16進制數(shù),因此最簡單的方法是以十六進制方式指定初 始值:
unsigned short font=0x064C; // Style 6, italic, 12 point
注釋:
在建立像這樣的位模式時,十六進制表示法要比十進制表示法更合適。
要使用字號,需要從font變量中提取它,這可以使用按位與運算符來實現(xiàn)。只有當(dāng)兩個位都是1時,按位與運算符才會產(chǎn)生1,所以可以定義一個值,在
將定義字號的位和font執(zhí)行按位與操作時選擇該位。為此,只需定義一個值,該值在我們感興趣的位上包含1,在其他位上包含0。這種值稱為掩碼,用下面的
語句定義它:
unsigned short size_mask=0x1F; //Mask is 0000 0000 0001 1111
//to select size
font變量的5個低位表示其字號,把這些位設(shè)置為1,剩余的位設(shè)置為0,這樣它們就會被舍棄(二進制數(shù)0000 0000 0001 1111可轉(zhuǎn)換為十六進制數(shù)1F)。
現(xiàn)在可以用下面的語句提取font中的字號了:
unsigned short size=font & size_mask;
在&操作中,當(dāng)兩個對應(yīng)的位是1時,結(jié)果位就是1。任何其他組合起來的結(jié)果就是0。因此組合起來的值如下:
font 0000 0110 0100 1100
size_mask 0000 0000 0001 1111
font & size_mask 0000 0000 0000 1100
把二進制值分解為4位一組的形式并不是很重要,這只是易于表示對應(yīng)的十六進制數(shù),看出其中有多少位。掩碼的作用是把最右邊的5位分隔出來,這5位表示點數(shù)(即字號)。
可以使用同樣的方法選擇字體的樣式,只是還需要使用按位移動運算符把樣式值向右移動。可以用下面的語句定義一個掩碼,選擇左邊的8位,如下所示:
unsigned short style_mask=0xFF00; //Mask is 1111 1111 0000 0000
//for style
用下面的語句獲取樣式值:
unsigned short style=(font & style_mask) >> 8; //Extract the style
該語句的結(jié)果如下:
font 0000 0110 0100 1100
style_mask 1111 1111 0000 0000
font & style_mask 0000 0110 0000 0000
(font & style_mask) >> 8 0000 0000 0000 0110
為表示斜體和黑體的位定義掩碼,并把相應(yīng)的位設(shè)置為1,就很容易把它們分隔出來。當(dāng)然,還需要一種方式來測試得到的位,這部分內(nèi)容詳見第4章。
按位與運算符的另一個用途是關(guān)閉位。前面介紹的是掩碼中為0的位在結(jié)果中也將輸出0。例如,為了關(guān)閉表示斜體的位,其他的位不變,只需定義一個掩
碼,使該掩碼中的斜體位為0,其他位為1,再對font變量和該掩碼進行按位與操作即可。實現(xiàn)此操作的代碼將在按位或運算符一節(jié)中介紹。
2. 使用按位或運算符
可以使用按位或運算符設(shè)置一個或多個位。繼續(xù)操作前面的font變量,現(xiàn)在需要設(shè)置斜體和黑體位。用下面的語句可以定義掩碼,選擇這些位:
unsigned short italic=0x40U; //Seventh bit from the right
unsigned short bold=0x20U; //Sixth bit from the right
用下面的語句設(shè)置黑體位:
font |= bold; // Set bold
位的組合如下:
font 0000 0110 0100 1100
bold 0000 0000 0010 0000
font | bold 0000 0110 0110 1100
現(xiàn)在,font變量指定它表示的字體是黑體和斜體。注意這個操作會設(shè)置位,而不考慮以前的狀態(tài)。如果以前位的狀態(tài)是開,則現(xiàn)在仍保持開的狀態(tài)。
也可以對掩碼執(zhí)行按位或操作,設(shè)置多個位。下面的語句就同時設(shè)置了黑體和斜體:
font |= bold | italic; //Set bold and italic
該語言很容易讓人選擇錯誤的運算符。“設(shè)置斜體和黑體”很容易讓人覺得應(yīng)使用&運算符,而這是錯誤的。對兩個掩碼執(zhí)行按位與操作會得到一個所有位都是0的值,這不會改變字體的任何屬性。
如上一節(jié)最后所述,可以使用&運算符關(guān)閉位。也就是定義一個掩碼,把其中要關(guān)閉的位設(shè)置為0,其他位設(shè)置為1。但如何指定這樣的掩碼?如果
要顯式指定它,就需要知道變量中有多少個字節(jié),如果希望程序可以任何方式移植,這就不很方便。可是,在通常用于打開位的掩碼上使用按位求反運算符,就可以
得到這樣的掩碼。在bold掩碼上關(guān)閉黑體位,就可以得到該掩碼:
bold 0000 0000 0010 0000
~bold 1111 1111 1101 1111
按位求反運算符的作用是反轉(zhuǎn)原數(shù)值中的每一位,使0變成1,1變成0。無論bold變量占用2個字節(jié)、4個字節(jié)還是8個字節(jié),這都會生成我們期望的結(jié)果。
提示:
按位求反運算符有時稱為NOT運算符,因為對于它操作的每個位,都會得到跟開始不同的值。
因此,在關(guān)閉黑體位時,只需對掩碼bold的反碼和font變量執(zhí)行按位與操作,可用的語句如下所示:
font &= ~bold; //Turn bold off
還可以使用&運算符把幾個掩碼組合起來,再對結(jié)果跟要修改的變量執(zhí)行按位與操作,將多個位設(shè)置為0。例如:
font &= ~bold & ~italic; //Turn bold and italic off
這個語句把font變量中的斜體和黑體位設(shè)置為0。注意這里不需要括號,因為~運算符的優(yōu)先級高于&運算符。但是,如果不清楚運算符的優(yōu)先級,就應(yīng)加上括號,表示希望執(zhí)行的操作。這肯定是無害的,在需要括號時還可以正常發(fā)揮作用。
3. 使用按位異或運算符
按位異或運算符的使用頻率遠(yuǎn)遠(yuǎn)低于&和 |
運算符,有關(guān)它的使用例子也比較少。但它的一個重要應(yīng)用是圖形編程。在屏幕中創(chuàng)建動畫的一種方式是繪制一個對象,刪除它,再在一個新位置重新繪制。如果要
求動畫很平滑,這個過程就需要重復(fù)得很快,其中刪除是一個重要的部分。我們并不想刪除和重新繪制整個屏幕,因為這非常費時,屏幕也會出現(xiàn)閃爍。最理想的
是,只刪除屏幕上要移動的對象。使用所謂的異或模式就可以做到這一點,得到非常平滑的 動畫。
異或模式的理念是,在屏幕上用給定的顏色繪制對象,如果接著用背景色重新繪制它,它就會消失。如圖3-3所示。

圖3-3 用異或模式繪圖
以異或模式在屏幕上繪制對象時,每次繪制對象的顏色會自動在為對象所選的顏色和背景色之間來回變化。得到這一效果的關(guān)鍵是使用按位異或運算符快速而
自動地改變顏色。它使用異或運算符的一個特性,即如果對兩個值進行異或操作,再對所得的結(jié)果和一個原始值執(zhí)行異或操作,就會得到另一個值。這聽起來很復(fù)
雜,下面就用一個例子來說明。
假定要在前景色(這里使用紅色)和背景色(白色)之間來回切換。顏色通常用3個8位值來表示,分別對應(yīng)于紅、藍(lán)、綠的亮度,存儲在一個4字節(jié)的整數(shù)
中。通過改變顏色中的紅、藍(lán)和綠的比例,就可以獲得大約1600萬種不同的顏色,包括從白色到黑色之間的所有顏色。純紅色是0xFF0000,這時紅色成
分設(shè)置為其最大值,其他兩種顏色即藍(lán)色和綠色的成分設(shè)置為0。在相同顏色模式下,綠色就是0xFF00,藍(lán)色是0xFF。在白色中,紅、藍(lán)、綠的成分具有
相同的最大值,即0xFFFFFF。
可以用下面的語句定義表示紅色和白色的變量:
unsigned long red=0XFF0000UL; //Color red
unsigned long white=0XFFFFFFUL; //Color white-RGB all maximum
接著創(chuàng)建一個掩碼,用于在紅色和白色之間來回切換,并把包含繪圖顏色的變量初始化為紅色:
unsigned long mask=red ^ white; //Mask for switching colors
unsigned long draw_color=red; //Drawing color
變量mask初始化為要切換的兩種顏色的按位異或操作結(jié)果,因此:
red 1111 1111 0000 0000 0000 0000
white 1111 1111 1111 1111 1111 1111
mask(即red ^ white) 0000 0000 1111 1111 1111 1111
如果對mask和red執(zhí)行異或操作,就會得到white,如果對mask和white執(zhí)行異或操作,就會得到red。因此,使用draw_color中的顏色繪制對象,就可以通過下面的語句切換顏色:
draw_color ^= mask; //Switch the drawing color
當(dāng)draw_color包含red時,其執(zhí)行過程如下:
draw_color 1111 1111 0000 0000 0000 0000
mask 0000 0000 1111 1111 1111 1111
draw_color ^ mask 1111 1111 1111 1111 1111 1111
顯然,draw_color的值從紅色變?yōu)榘咨T俅螆?zhí)行這個語句,就會把顏色改回為紅色:
draw_color^=mask; //Switch the drawing color
其執(zhí)行過程如下:
draw_color 1111 1111 1111 1111 1111 1111
mask 0000 0000 1111 1111 1111 1111
draw_color ^ mask 1111 1111 0000 0000 0000 0000
draw_color又變成了紅色。這個技術(shù)適用于任意兩種顏色,當(dāng)然它實際上與特定顏色沒有一點關(guān)系,可以把它用于切換任意一對整型數(shù)值。
程序示例3.4—— 使用按位運算符
下面用一個例子來試驗按位運算符,看看它們?nèi)绾我黄鸸ぷ鳌1纠€演示了如何使用異或運算符在兩個值之間切換,以及如何使用掩碼來選擇和設(shè)置各個位。代碼如下:
//Program 3.4 Using the bitwise operators
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::setfill;
using std::setw;
int main() {
unsigned long red=0xFF0000UL; //Color red
unsigned long white=0xFFFFFFUL; //Color white - RGB all maximum
cout << std::hex; //Set hexadecimal output format
cout << setfill('0'); //Set fill character for output
cout << "\nTry out bitwise AND and OR operators.";
cout << "\nInitial value red = "<< setw(8) << red;
cout << "\nComplement ~red = "<< setw(8) <<~ red;
cout << "\nInitial value white = "<< setw(8) << white;
cout << "\nComplement ~ white = "<< setw(8) <<~ white;
cout << "\n Bitwise AND red & white = " << setw(8) << (red & white);
cout << "\n Bitwise OR red | white = " << setw(8) << (red | white);
cout << "\n\nNow we can try out successive exclusive OR operations.";
unsigned long mask=red ^ white;
cout << "\n mask= red ^ white = " << setw(8) << mask;
cout << "\n mask ^ red = " << setw(8) << (mask ^ red);
cout << "\n mask ^ white = " << setw(8) << (mask ^ white);
unsigned long flags=0xFF; //Flags variable
unsigned long bit1mask=0x1; //Selects bit 1
unsigned long bit6mask=0x20; //Selects bit 6
unsigned long bit20mask=0x80000; //Selects bit 20
cout << "\n\nNow use masks to select or set a particular flag bit.";
cout << "\nSelect bit 1 from flags : " << setw(8) << (flags & bit1mask);
cout << "\nSelect bit 6 from flags : " << setw(8) << (flags & bit6mask);
cout << "\nSwitch off bit 6 in flags : " << setw(8) << (flags &= ~bit6mask);
cout << "\nSwitch on bit 20 in flags : " << setw(8) << (flags |= bit20mask);
cout <<endl;
return 0;
}
該例子的輸出如下:
Try out bitwise AND and OR operators.
Initial value red = 00ff0000
Complement ~red = ff00ffff
Initial value white = 00ffffff
Complement ~ white = ff000000
Bitwise AND red & white = 00ff0000
Bitwise OR red | white = 00ffffff
Now we can try out successive exclusive OR operations.
mask= red ^ white =0000ffff
mask ^ red = 00ffffff
mask ^ white =00ff0000
Now use masks to select or set a particular flag bit.
Select bit 1 from flags : 00000001
Select bit 6 from flags : 00000020
Switch off bit 6 in flags : 000000df
Switch on bit 20 in flags : 000800df
例子的說明
本例中添加了對標(biāo)準(zhǔn)頭文件<iomanip>的#include指令,這個頭文件在第2章介紹過,因為代碼將使用操縱程序控制輸出的格式。首先,定義兩個整數(shù)變量,它們包含的值表示要用于后續(xù)按位運算的顏色:
unsigned long red=0xFF0000UL; //Color red
unsigned long white=0xFFFFFFUL; //Color white - RGB all maximum
為了把數(shù)據(jù)顯示為十六進制值,可用下面的語句指定:
cout << std::hex; //Set hexadecimal output format
其中hex是一個操縱程序,它把整數(shù)值的輸出表示為十六進制。注意,這是模式化的,該程序以后在標(biāo)準(zhǔn)輸出流中的所有整數(shù)輸出都采用十六進制格式。不需要把hex發(fā)送給輸出流cout。如果需要,可以用下面的語句把輸出格式改回為十進制:
cout << std::dec; //Set decimal output format
這個語句使用dec操縱程序,把整數(shù)輸出重新設(shè)置為默認(rèn)的十進制表示。注意,把輸出格式設(shè)置為十六進制,僅影響整數(shù)值。浮點數(shù)值會繼續(xù)顯示為一般的十進制。
如果在輸出整數(shù)時加上前導(dǎo)0,就會使結(jié)果更清晰易懂。用下面的語句設(shè)置這種模式:
cout << setfill('0'); //Set fill character for output
其中setfill()是一個操縱程序,它把填充字符設(shè)置為括號中的字符。這也是模式化的,這樣,以后的所有整數(shù)輸出都會在需要時使用這個填充字符。它對十進制和十六進制輸出都起作用。如果要用星號代替該填充字符,則可以使用下面的語句:
cout << setfill('*'); //Set fill character for output
要把填充字符設(shè)置回原來的默認(rèn)值,只需在括號中使用空格:
cout << setfill(' '); //Set fill character for output
下面的語句顯示red的值及其反碼:
cout << "\nInitial value red = "<< setw(8) << red;
cout << "\nComplement ~red = "<< setw(8) <<~ red;
這里使用第2章介紹的setw()操縱程序,把輸出字段寬度設(shè)置為8。如果所有的輸出值都采用相同的字段寬度,就很容易比較它們。設(shè)置寬度不是模式化的,它只應(yīng)用于跟在字段寬度設(shè)置點后面的下一條語句的輸出。在red和white的輸出中,~運算符反轉(zhuǎn)了其操作數(shù)的位。
下面的語句使用按位與以及按位或運算符來合并red和white:
cout << "\n Bitwise AND red & white = " << setw(8) << (red & white);
cout << "\n Bitwise OR red | white = " << setw(8) << (red | white);
注意輸出中表達(dá)式的括號。它們是必需的,因為<<的優(yōu)先級高于&和|。沒有括號,該語句就不會編譯。如果查看一下輸出,就會看
出它跟這里討論的相同。若對兩個值都為1的位執(zhí)行按位與操作,就會得到1,否則結(jié)果就是0。在對兩個位執(zhí)行按位或操作時,除非兩個位都是0,否則結(jié)果就是
1。
然后,創(chuàng)建一個掩碼,在通過按位異或運算符組合兩個值時,該掩碼用于反轉(zhuǎn)red和white的值。
unsigned long mask=red ^ white;
如果查看一下mask值的輸出,就會發(fā)現(xiàn)在兩個位的值不同時,對兩個位執(zhí)行異或操作的結(jié)果是1,在兩個位的值相同時,該操作的結(jié)果是0。利用異或運算符把mask和兩個顏色值中的一個組合起來,就會得到另一個顏色值。這可以用下面的語句來說明:
cout << "\n mask ^ red = " << setw(8) << (mask ^ red);
cout << "\n mask ^ white = " << setw(8) << (mask ^ white);
最后一組語句演示了如何使用掩碼從一組標(biāo)記位中選擇一個位。選擇某個位的掩碼必須使該位的值為1,其他位的值為0。因此,從一個32位long變量中選擇第1、6和20位的掩碼定義如下:
unsigned long bit1mask=0x1; //Selects bit 1
unsigned long bit6mask=0x20; //Selects bit 6
unsigned long bit20mask=0x80000; //Selects bit 20
要從flags中選擇一個位,只需對相應(yīng)的掩碼和flages的值執(zhí)行按位與操作。例如:
cout << "\nSelect bit 6 from flags : " << setw(8) << (flags & bit6mask);
從輸出中可以看到,表達(dá)式(flags & bit6mask)的結(jié)果是只設(shè)置了第6位的整數(shù)。當(dāng)然,如果flages中的第6位為0,該表達(dá)式的結(jié)果就是0。
要關(guān)閉一個位,需要對flages變量和一個掩碼執(zhí)行按位與操作。在該掩碼中,要關(guān)閉的那個位是0,其他位是1。對掩碼和對應(yīng)的位執(zhí)行按位求反操作,也可以關(guān)閉該位。bit6mask就是這樣的一個掩碼。下面的語句把flags中的第6位關(guān)閉,并顯示結(jié)果:
cout << "\nSwitch off bit 6 in flags : " << setw(8) << (flags &= ~bit6mask);
當(dāng)然,如果第6位已經(jīng)是0,該位就保持不變。要打開一個位,只需對flages和一個掩碼執(zhí)行按位或操作,在該掩碼中,要打開的那個位是1:
cout << "\nSwitch on bit 20 in flags : " << setw(8) << (flags |= bit20mask);
這個語句把flags中的第20位設(shè)置為1,并顯示結(jié)果。如果這個位已經(jīng)是1,該位將保持不變。
4. 輸出操縱程序
把第2章介紹的也算在內(nèi),到目前為止我們已介紹了5個模式化輸出操縱程序,它們都是在<iostream>頭文件中定義
的:scientific、fixed、dec、hex和oct。表3-2列出所有的其他相似的操縱程序。目前不介紹后兩項中的bool值,它將在第4章
討論。
表3-2 輸出操縱程序
操 縱 程 序
|
執(zhí)行的動作
|
dec
|
把整數(shù)值格式化為十進制。這是默認(rèn)的表示法
|
hex
|
把整數(shù)值格式化為十六進制
|
oct
|
把整數(shù)值格式化為八進制
|
left
|
使輸出字段中的值左對齊,其右端用填充字符填充。默認(rèn)的填充字符是空格
|
right
|
使輸出字段中的值右對齊,其左端用填充字符填充。這是默認(rèn)的對齊方式
|
fixed
|
以固定點表示法輸出浮點數(shù)值,即不帶指數(shù)
|
scientific
|
以科學(xué)表示法輸出浮點數(shù)值,即尾數(shù)加指數(shù)的方式。默認(rèn)的模式根據(jù)要顯示的數(shù)值,選擇fixed或scientific表示法
|
showpoint
|
給浮點數(shù)值顯示小數(shù)點和尾部的0
|
noshowpoint
|
與上一個操縱程序相反。這是默認(rèn)的
|
showbase
|
在八進制的輸出前面加上前導(dǎo)0,在十六進制的輸出前面加上前導(dǎo)0x或0X
|
noshowbase
|
八進制和十六進制的輸出中不顯示前綴。這是默認(rèn)的
|
showpos
|
正數(shù)前面加上+號
|
noshowpos
|
正數(shù)前面不顯示+號,這是默認(rèn)的
|
uppercase
|
在以十六進制格式輸出整數(shù)時,給十六進制數(shù)字顯示大寫字母A到F。如果設(shè)置了showbase,還要顯示0X。在以科學(xué)計數(shù)法輸出數(shù)值時,給指數(shù)顯示E,而不是使用小寫字母e
|
nouppercase
|
對上述項使用小寫字母,這是默認(rèn)的
|
boolalpha
|
把bool值顯示為true和false
|
noboolalpha
|
把bool值顯示為1和0
|
可以一次設(shè)置多種模式,方法是在流中插入多個操縱程序。例如,如果要把整型數(shù)據(jù)輸出為十六進制值,且在輸出字段中左對齊,就可以使用下面的語句:
std::cout << std::hex << std::left << value;
這個語句會把value(以及程序中后續(xù)的所有整數(shù),除非改變了設(shè)置)輸出為左對齊的十六進制數(shù)值。
表3-3列出了需要提供參數(shù)值的輸出操縱程序。
表3-3 需要參數(shù)的輸出操縱程序
操 縱 程 序
|
執(zhí)行的動作
|
setfill()
|
把填充字符設(shè)置為參數(shù)指定的字符。默認(rèn)的填充字符是空格
|
setw()
|
把字段寬度設(shè)置為參數(shù)指定的值
|
setprecision()
|
把浮點值的精度設(shè)置為參數(shù)指定的值。精度是輸出中十進制數(shù)字的個數(shù)
|
Tag標(biāo)簽:
c++ ,
按位運算符,
與或非