【C++注意事項】1 資料型別及型別轉換

nomasp發表於2015-05-20

如何選擇型別

1)當數值不可能為負時,選擇無符號型別。

2)當數值超過了int的表示範圍時,選用long long。

3)在算術表示式中不要使用char或bool,只有在存放字串或布林值時才使用它們。因為型別char在一些機器中是有符號的,而在另一些機器中又是無符號的。如果你需要使用一個不大的整數,那麼明確指定它的型別是signed char或者unsigned char。

4)執行浮點數運算選用double,這是因為float通常精度不夠而且雙精度浮點數和單精度浮點數的計算代價相差無幾。事實上,對於某些機器而言,雙精度運算甚至比單精度還快。long double提供的精度在一般情況下是沒有必要的,況且它帶來的運算時間消耗也是不容小覷的。

型別轉換

1)當我們把一個非布林型別的算術值賦給布林型別時,初始值為0則結果為false,否則結果為true。

2)當我們把一個布林值賦給非布林型別時,初始值為false則結果為0,初始值為true則結果為1.

3)當我們把一個浮點數賦給整數型別時,進行了近視處理。結果值將保留浮點數中小數點之前的部分。

4)當我們賦給無符號型別一個超出它表示範圍的值時,結果是初始值對無符號型別表示數值總數取模後的餘數。例如,8位元大小的unsigned char可以表示0至255區間的值,如果我們賦了一個區間以外的值,則實際的結果是該值對256取模後所得的餘數。因此,把-1賦給8位元大小的unsigned char所得的結果是255。

5)當我們賦給帶符號型別一個超出它表示範圍的值時,結果是未定義的(undefined)。此時,程式可能繼續工作、可能崩潰,也可能生成垃圾資料。

無符號數的轉換

下面再來展示一個有意思的程式碼片。

unsigned u = 10;
int i = -42;
cout<<i + i<<endl;  // 輸出:-84
cout<<u + i<<endl;  // 輸出:4294967264

第一個輸出應該就不用說了,對於第二個,首先將-42轉換成無符號數,把負數轉換成無符號數類似於直接給無符號數賦一個負值,結果就等於這個負數加上無符號數的摸。是不是有些拗口呢?看看下面的程式碼呢?

int i = -42;
unsigned w=i;
cout<<w<<endl;  // 輸出為:4294967254

在來看看下面這段程式碼:

unsigned u1=42,u2=10;
cout<<u2-u1<<endl;  // 輸出:4294967264
unsigned u=-32;
cout<<u<<endl;  // 輸出:4294967264  和上面的兩段程式碼一樣,都是將-32轉換為無符號數

還有一點需要注意的。比如在寫一個將數字從10到0的降序輸出時,考慮到無符號數不會小於0這一鐵律,你是否會這樣寫呢?

for(unsigned i =10; i>=0; --i)
    cout<<i<<endl;

這是一個陷阱…… 因為當i等於0的時候,輸出0是顯然的,然而在繼續執行for迴圈中的自減操作後得到了-1,-1並不滿足無符號數的要求,因此就像前面的例子那樣就被轉換成了一個合法的無符號數(4294967295)。

解決這個問題的關鍵在於要在輸出變數之前先減去1。這樣的話,如果迴圈從10開始,減去1後輸出結果就成了9到0了,因此初始化時要設定為11。

而且最終截斷點不應該是i==0,而應該是i>0,所以應該這樣改:

for(unsigned i =11; i>0;)
{
    --i;
    cout<<i<<endl;
}

當然了,既然截斷點是大於0,這正好可以用上while迴圈了。

unsigned i =11;
while(i>0)  // 此處寫成 while(i) 也是可以的
{
    --i;
    cout<<i<<endl;
}

備註:該【C++注意事項】系列參考了《C++ Prime 》一書和網路資源,主要用於給自己複習、總結,也希望對廣大讀者有幫助。



感謝您的訪問,希望對您有所幫助。 歡迎大家關注、收藏以及評論。

我的更多部落格文章:NoMasp部落格導讀


為使本文得到斧正和提問,轉載請註明出處:
http://blog.csdn.net/nomasp


相關文章