//=====================================================================
//TITLE:
// C++ VS C#(3):switch,類型轉換
//AUTHOR:
// norains
//DATE:
// Tuesday 1-December-2010
//Environment:
// Visual Studio 2010
// Visual Studio 2005
//=====================================================================
1. switch
C++和C#都有switch關鍵字,只不過,兩者間還是有一定的區別的。最大的區別就是,在C#中,如果case之後有語句,那麼必須要以break跳出switch。簡單點來說,下面這個語句雖然在C++中是一切正常,但在C#中卻是無法編譯通過的:switch (iSelect)<br />{<br /> case 1:<br /> iVal = 1;<br /> break;<br /> case 2:<br /> iVal = 2;<br /> case 3:<br /> iEnd = 3;<br /> break;<br />}
C#中會提示錯誤:error CS0163: Control cannot fall through from one case label ('case 2:') to another。也就是說,“case 2:”不能穿越到“case 3:”。那麼,是不是意味著“case 2:”和“case 3:”無法執行同一代碼呢?答案當然不是,其實只要“case 2:”和“case 3:”之間沒語句即可:switch (iSelect)<br />{<br /> case 1:<br /> iVal = 1;<br /> break;<br /> case 2:<br /> case 3:<br /> iEnd = 3;<br /> break;<br />}
更改之後的代碼能夠順利在C#中順利編譯通過。通過這個例子可以知道,switch在C++中靈活性高,在C#則是安全性強——畢竟忘記寫break的還是大有人在。
C#對switch還有一個改進之處在於,判定條件可以採用字串,比如:switch (strVal)<br />{<br /> case "A":<br /> break;<br /> case "B":<br /> case "C":<br /> break;<br />}
這個程式碼片段不能在C++中編譯通過,但在C#中卻是一切正常,因為在C++中,判定的條件一定要為數實值型別。這也是沒辦法的事情,字串在C#中是一個標準的內建類型,但在C++卻是STL衍生的一個類。
2. 類型轉換
這兩種語言在類型轉換上都有兩種方式,分別是隱式轉換和顯式轉換。這裡有個小細節需要注意,在C#中,凡是能夠進行隱形轉換的,數值都是無損的。這樣說起來可能有點拗口,我們來看看這段代碼:byte nVal = 0;<br />int iVal = 2000;<br />nVal = iVal;
這個代碼在給nVal賦值時有個隱式轉換,也就是將int轉為byte,除非iVal的數值在於0~255,否則肯定會精度丟失。在C++中,該代碼卻能夠進行編譯,不過在C#中就遭遇失敗,提示錯誤:error CS0266: Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)。
如果非要將int類型賦值給byte,C#中一定要進行顯式轉換轉換,如:nVal = (byte)iVal;
這時候C#的表現就和C++的一致,即使精度丟失,也會完成轉換。不過C#還留了一手,可以在轉換前增加checked來進行檢查,如:nVal = checked((byte)iVal);
當iVal的實際數值在byte類型的允許範圍之內,則一切都沒有問題;但如果範圍超出,則會彈出一個提示對話方塊,告訴你資料溢出,如:
對於C++來說,這種以括弧形式進行轉換的稱為舊方式,並不建議程式員使用。取而代之的是static_cast,reinterpret_cast,const_cast和dynamic_cast。說點題外話,我覺得對於編譯器而言,特別是在嵌入式系統領域,最難實現的應該是dynamic_cast。最典型的例子就是,你使用RVDS,帶有dynamic_cast的代碼是無法編譯通過的,但在MDK裡卻是一帆風順。
那麼C#呢,是否也有類似的XXX_cast?答案是否定的。C#另闢蹊徑,可以使用Convert對象。該對象的方法有很多,比如. ToByte,ToInt16等等。那為什麼會有括弧轉換的方式,又有對象函數的方式呢?理由很簡單,括弧轉換是屬於C#的,對象函數是屬於.Net Framework的。換句話來說,對象函數的方法,不僅適合C#,也適合VB,以及一切運行於.Net Framework上的語言。除此以外,這兩種方式還有一個很重要的區別,括弧轉換方式只能在數值中進行轉換,但對象函數卻能在大部分類型間進行,如:
string strVal = "22";<br />byte nVal = 0;<br />// nVal = (byte)strVal; //無法編譯通過<br />nVal = Convert.ToByte(strVal);//順利編譯
但字串轉換為數值,有一點必須要注意,就是字串的內容必須符合數值的格式,否則會出錯。比如,有如下程式碼片段:string strVal = "G";<br />byte nVal = 0;<br />nVal = Convert.ToByte(strVal);
執行Convert之後,會提示錯誤,