你好,C++(10)這次的C++考試你過了沒有?C++中表示邏輯判斷的布爾數據類型


3.4  布爾類型

在日常生活中,我們除了需要使用int類型的變量表示216路公交車;需要使用float類型的變量表示西紅柿3.5元一斤,有時候還需要表示一種數據,那就是邏輯狀態:

“這次的C++考試你過了沒有?”

“他到底愛不愛我?”

這里的“過了沒有”以及“愛不愛”都是表示一種邏輯判斷。與之前我們用數值數據類型表示的公交車線路以及西紅柿價格可以有多種取值不同,這種邏輯判斷狀態具有“非此即彼”的特殊性。對於考試狀態,要么是“過了”,要么是“沒過”,二者必選其一。正因為如此,在C++中,我們同樣也使用一種特殊的數據類型——布爾類型——來表達這種“非此即彼”的邏輯判斷狀態。布爾類型的變量只可以被賦予值true或者false,分別表示邏輯的真與假、是與非。布爾類型的說明符是“bool”。C++標准並沒有指定布爾類型數據的長度,在Visual C++中布爾類型占1個字節。例如:

// 布爾類型變量bPass,表示考試是否通過
// 賦值為true,表示考試通過
bool bPass = true;

與int等數值類型數據主要用於計算不同,布爾類型的數據主要用來保存邏輯判斷的結果,或者是用於條件結構或者循環結構(在稍后的第4章將詳細介紹)中,對程序的執行流程進行控制。例如:

cout<<"請輸入你的分數:"<<endl;
// 保存輸入分數的int類型變量
int nScore = 0;
// 輸入分數
cin>>nScore;
// 保存考試通過與否的bool類型變量
// 默認狀態為false,表示沒有通過
bool bPass = false;
// 用條件結構進行邏輯判斷
// 判斷輸入的分數是否大於等於60
if(nScore >= 60)
{
    // 保存邏輯判斷的結果
    // 如果輸入的分數大於等於60,則賦值為true,
   // 表示考試通過,否則繼續保留其初始值false,表示沒有通過
   bPass = true;
}

// 在條件結構中,根據bPass的取值不同,
// 對程序的執行路徑進行控制
if(bPass)
{
   // 如果bPass的值為true,輸出考試通過
   cout<<"恭喜,你通過了考試"<<endl;
}
else
{
   // 如果bPass的值為false,輸出考試未通過
   cout<<"很遺憾,你沒有通過考試"<<endl;
}

在這段代碼中,bPass這個bool類型的變量,首先用於保存邏輯判斷的結果,記錄了輸入的分數nScore是否大於等於60的邏輯判斷結果。如果nScore大於等於60,bPass就被賦值為true,否則,繼續保留它的初始值false,表示nScore沒有大於等於60。這樣,bPass這個bool類型的變量就保存了“nScore是否大於等於60”這個邏輯判斷的結果。

用bool類型變量保存邏輯判斷的結果,不僅僅是為了保存,更多的還是為了用在條件或者循環結構中對程序的執行流程進行控制。在其后的if條件結構中,bPass又被用作了條件判斷的依據,如果bPass的值為true,則輸出考試通過的提示,否則,就輸出考試未通過的提示。這樣,根據bPass這個bool類型變量的取值不同,我們的程序就有了不同的執行路徑。

最佳實踐:杜絕bool類型和整型的隱式轉換

雖然bool類型變量只有true和false這兩個邏輯值,但當其使用在一個需要數值算術值的地方時,bool類型變量的值將被隱式地轉換成為一個整型數值。如果bool類型變量的值是false,則轉換后參與運算的值就是0;反之就是1。反過來,如果我們把一個數值(整數或小數)賦值給一個bool類型變量,那么也會發生從數值數據到bool類型數值的隱式轉換。數值0會被轉換為為false,而其他任何非0的數值會被轉換為true。例如:

bool a = 4;     // 4被轉換為true,a的值為true
int b = a;     // a被轉換為1,b的值為1
int c = a + b;  // a被轉換為1參與運算,c的值為2

這種轉換發生得非常隱蔽,某些編譯器甚至連警告信息都不會給出。而一旦代碼的行為非常隱蔽,這就意味着其中很可能會隱藏着一些不容易被察覺的錯誤。所以我們應當盡量避免用數值為bool類型的變量賦值,或者是將bool類型的變量用於算術運算,杜絕這種“偷偷摸摸”的小動作的發生。

3.5  字符與字符串類型

“你的車牌號是多少?”

“陝A-82103”

我們知道,程序設計語言本質上是用來抽象、描述和表達現實世界的。面對現實世界中的各種數值數據(比如,表示公交車路線的216路,表示西紅柿價格的3.5元一斤),我們可以用之前所介紹的數值數據類型定義變量(int nNo,float fPrice)來抽象和表達。除此之外,現實世界中還有另外一類數據——文字數據,比如上面例子中的車牌號“陝A-82103”就是一個文字數據。為了表達這一類文字數據,C++提供了字符類型和字符串類型兩種數據類型專門用於抽象和表達文字數據。其中,字符類型用於表達單個的字符,比如‘A’、‘0’等等,而多個字符串聯起來形成的字符串,我們則使用字符串類型來表達。

3.5.1 字符類型

在學習英語的時候,我們總是從ABC單個字母開始學習的,然后才能串聯起來形成一句完整的話。而要想在C++中用字符串表達一個比較復雜的文字數據,我們同樣也得從構成字符串的單個字符開始學起。在C++中,我們用字符類型來抽象和表達單個的常見字符,其類型說明符是“char”。例如:

// 定義字符類型變量cA,並用字符常量‘A’對其進行賦值
char cA = 'A'; // cA變量表示大寫字母字符‘A’
char cB;
cB = '-';  // cB變量表示符號字符‘-’
// 輸出字符‘A’
cout<<cA<<endl;

雖然字符類型的變量總是以字符的面目出現(賦值和輸出),但在本質上,它其實可以看作是一種占用內存空間更少取值范圍更小的整型數據類型。它只占用1 個字節的內存空間,相應的其取值范圍也縮小為-128~127。當我們需要表達一個取值比較小的整數時,為了節省內存資源,我們可以使用char類型來表達。跟整型數據類型一樣,字符類型也可以受到signed/unsigned關鍵字的修飾,形成有/無符號的字符類型。因此,char類型也可以參與算術運算。例如:

// 將大寫字母字符‘A’對應的ASCII碼值賦值給字符類型變量c
// 等價於char c = ‘A’;
char c = 65;
// 變量t表示不可見的控制字符‘\t’,表示輸出一個Tab控制
char t = '\t';
// 循環輸出26個大寫字母字符
for(int i = 0; i < 26; ++i)
{
    // 輸出c所代表的字符
    cout<<c<<t;

    // 字符類型變量加1,使其成為ASCII表中的下一個字符
    c = c + 1;
}

知道更多:用wchar_t表示中文字符

因為char字符類型取值范圍有限,只能用來表示有限的ANSCII字符表中的字符,包括常見的字母字符和控制字符等。而如果要表示更大范圍內的字符,比如上面例子中的‘陝’這個中文字符,char就顯得鞭長莫及了。為了彌補char類型的不足,C++提供了另外一種字符數據類型wchar_t,它占用2個字節的內存空間,取值范圍更廣,因而可以表示更大范圍的字符,當然也包括中文字符了。例如,可以通過下面的方式來輸出一個中文字符。不過這里需要注意的是,因為我們的代碼中有擴展的中文字符,所以要求我們的代碼文件使用UTF-8的編碼格式進行保存。

// 定義一個wchar_t類型字符變量
// 並用一個中文字符對其賦值
wchar_t cChs = L'';
// 設置wcout輸出對象的區域並輸出中文字符
wcout.imbue ( locale ( "chs" ) );
wcout<<cChs<<endl;

這里值得提醒的是,字符常量或字符串常量前面的L前綴,表示對這里的字符或字符串采用wide-character字符集(寬字符集,通常是UNICODE字符集)對其進行編碼。而如果不使用L前綴,則表示使用multibyte-character字符集(多字節字符集)對其進行編碼。所以,如果我們要用某個字符或字符串常量對一個寬字符(wchar_t)或寬字符串(wstring)變量進行初始化或賦值時,我們應該在這個字符或字符串常量前加上L前綴。反之,如果是對char和string類型的變量進行初始化或賦值時,則不需要添加L前綴。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM