- PEVR虚拟现实编辑平台设计与实现精析
- 浙江优创信息技术有限公司
- 1609字
- 2025-02-27 13:46:11
2.1.1 条件语句
当程序中需要进行两个或两个以上的选择时,可以根据条件判断来选择将要执行的一组语句,C#提供的选择语句有if语句和switch语句。
2.1.1.1 if语句
if语句是最常用的选择语句,它根据布尔表达式的值来判断是否执行后面的内嵌语句格式,其形式为

当布尔表达式的值为真,则执行if后面的内嵌语句embedded-statement;当布尔表达式的值为假,则程序继续执行。如果有else语句,则执行else后面的内嵌语句,否则继续执行下一条语句。
例如下面的例子用来对一个浮点数x进行四舍五入,结果保存到一个整数i中:

如果if或else之后的嵌套语句只包含一条执行语句,则嵌套部分的大括号可以省略;如果包含了两条以上的执行语句,对嵌套部分一定要加上大括号;如果程序的逻辑判断关系比较复杂,通常会采用条件判断嵌套语句,if语句可以嵌套使用,即在判断之中又有判断,具体形式如下:

此时应该注意每一条else与离它最近且没有其他else与之对应的if相搭配,比如有下面一条语句:

它实际上应该等价于下面的写法:

注意C#的if语句与C、C++不同,即if后的逻辑表达式必须是布尔类型的。
请看一个判断是否往应用程序传送参数的例子:
程序清单 2-1:

其中args.Length==0是一个布尔表达式,但是C或者C++程序员可能会习惯编写像这样的代码:

这在C#中是不允许的,因为if语句仅允许布尔类型的结果,而字符串的Length属性对象返回一个整型(integer),编译器将报告错误信息。
2.1.1.2 switch语句
if语句每次判断只能实现两条分支,如果要实现多种选择的功能,那么可以采用switch语句。switch语句根据一个控制表达式的值选择一个内嵌语句分支来执行。它的一般格式为

switch语句的控制类型,即其中控制表达式(controlling-expression)的数据类型可以是sbyte、byte、short、ushort、uint、long、ulong、char、string或枚举类型(enum-type)。每个case标签中的常量表达式(constant-expression)必须属于或能隐式转换成控制类型,如果有两个或两个以上case标签中的常量表达式值相同,编译时将会报错。switch语句中最多只能有一个default标签。我们举一个例子来说明switch语句是如何实现程序的多路分支的:假设考查课的成绩按优秀、良好、中等、及格和不及格分为五等,分别用4、3、2、1、0来表示,但实际的考卷为百分制,对应的分数分别为90~100、80~89、70~79、60~69、60分以下。下面的程序将考卷成绩x转换为考查课成绩y,代码如下:


下面的例子判断传递给应用程序的参数的有无及位数:
程序清单 2-2:

使用switch语句时需注意以下两点:
1.不准遍历
C和C++语言允许switch语句中case标签后不出现break语句,但C#不允许这样,它要求每个标签项后使用break语句或跳转语句goto,即不允许从一个case自动遍历到其他case,否则编译时将报错。
一个程序用于计算一年中已度过的天数,month表示月份,day表示日期,计算结果保存在total中。为简便起见把闰年的情况排除在外,C和C++程序员会利用一点技巧来实现这个程序:


然而这种写法在C#中是不允许的。很难保证任何人在编程时都不会忘记在case后加上break语句,这时往往会造成一些不易察觉的错误,所以在C#中如果标签项没有出现break语句或跳转语句goto,编译器将会要求程序员加上。
如果想像C、C++那样,执行完后继续遍历其他的语句,那也不难,只需要明确地加入这两条跳转语句即可:
➢ goto case label:跳至标签语句执行
➢ goto default:跳至default标签执行
那样上面的程序可以改写为

在避免了C、C++中常出现的由于漏写break而造成的错误的同时不准遍历的原则,还使得我们可以任意排列switch语句中的case项而不会影响switch语句的功能。另外,一般说来每个switch项都以break、goto、case或goto、default结束,但实际上任何一种不导致遍历的结构都是允许的,例如throw和return语句同样可以跳出控制之外,因而下例是正确的:

2.把字符串当成常量表达式
VB的程序员可能已经习惯把字符串当成常量表达式来使用,但C和C++却不支持这一点,C#的switch语句与C、C++的另一个不同点是:C#可以把字符串当成常量表达式来使用,所以switch语句的控制类型可以是string类型。
下面的例子实现浮动窗口提示。在Windows操作系统中,把鼠标移到某一个控件上停留几秒,将会出现一个浮动提示,说明该控件的作用。例子中的GetButtonCaption用于获得按钮上的文字,ShowMessage表示在浮动提示窗口中显示信息:
