C++ VS C#(3):switch,类型转换
//=====================================================================
//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#中却是无法编译通过的:view plaincopy to clipboardprint?
switch (iSelect)
{
case 1:
iVal = 1;
break;
case 2:
iVal = 2;
case 3:
iEnd = 3;
break;
}
switch (iSelect)
{
case 1:
iVal = 1;
break;
case 2:
iVal = 2;
case 3:
iEnd = 3;
break;
}
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:”之间没语句即可:view plaincopy to clipboardprint?
switch (iSelect)
{
case 1:
iVal = 1;
break;
case 2:
case 3:
iEnd = 3;
break;
}
switch (iSelect)
{
case 1:
iVal = 1;
break;
case 2:
case 3:
iEnd = 3;
break;
}
更改之后的代码能够顺利在C#中顺利编译通过。通过这个例子可以知道,switch在C++中灵活性高,在C#则是安全性强——毕竟忘记写break的还是大有人在。
C#对switch还有一个改进之处在于,判定条件可以采用字符串,比如:view plaincopy to clipboardprint?
switch (strVal)
{
case "A":
break;
case "B":
case "C":
break;
}
switch (strVal)
{
case "A":
break;
case "B":
case "C":
break;
}
这个代码段不能在C++中编译通过,但在C#中却是一切正常,因为在C++中,判定的条件一定要为数值类型。这也是没办法的事情,字符串在C#中是一个标准的内置类型,但在C++却是STL衍生的一个类。
2. 类型转换
这两种语言在类型转换上都有两种方式,分别是隐式转换和显式转换。这里有个小细节需要注意,在C#中,凡是能够进行隐形转换的,数值都是无损的。这样说起来可能有点拗口,我们来看看这段代码:view plaincopy to clipboardprint?
byte nVal = 0;
int iVal = 2000;
nVal = iVal;
byte nVal = 0;
int iVal = 2000;
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#中一定要进行显式转换转换,如:view plaincopy to clipboardprint?
nVal = (byte)iVal;
nVal = (byte)iVal;
这时候C#的表现就和C++的一致,即使精度丢失,也会完成转换。不过C#还留了一手,可以在转换前增加checked来进行检查,如:view plaincopy to clipboardprint?
nVal = checked((byte)iVal);
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上的语言。除此以外,这两种方式还有一个很重要的区别,括号转换方式只能在数值中进行转换,但对象函数却能在大部分类型间进行,如:
view plaincopy to clipboardprint?
string strVal = "22";
byte nVal = 0;
// nVal = (byte)strVal; //无法编译通过
nVal = Convert.ToByte(strVal);//顺利编译
string strVal = "22";
byte nVal = 0;
// nVal = (byte)strVal; //无法编译通过
nVal = Convert.ToByte(strVal);//顺利编译
但字符串转换为数值,有一点必须要注意,就是字符串的内容必须符合数值的格式,否则会出错。比如,有如下代码段:view plaincopy to clipboardprint?
string strVal = "G";
byte nVal = 0;
nVal = Convert.ToByte(strVal);
string strVal = "G";
byte nVal = 0;
nVal = Convert.ToByte(strVal);
执行Convert之后,会提示错误,如图:
补充:软件开发 , C++ ,