很少有程序从头到尾逐行连续执行。反之,程序的执行流程会是按条件的。当遇到某种条件时,可能需要程序执行特定的代码块,或者没遇到该条件时执行另一代码块。程序也可能需要重复执行同一段代码。C#语言能提供数种循环和其他控制结构流程,来适应这些情况。
1.11.1 if语句
if语句是基本的条件分支语句,在满足某条件时,执行一行或多行代码,该条件表现为一个逻辑表达式。当条件没有得到满足时,将执行else关键字后面的代码。if语句中的else子句是可选的。
if语句的基本语法如下所示:
if (condition) {
execute whatever code is contained within the braces if condition is met
}
或者,添加可选的else子句:
if (条件) {
execute whatever code is contained within the braces if condition is met
}
else {
execute whatever code is contained withia the braces if condition is NOT met
}
如果if或(可选的)else关键字后面只有一行可执行语句,则可以省略大括号:
// 伪代码。
if (condition) Single statement to execute if true;
else Single stretment to execute if false;
但通常认为总是使用大括号是好习惯。
单个布尔变量,作为布尔表达式的简单形式,自然也可用作if语句的逻辑表达式或条件。例如,下面的写法完全可接受:
// 使用这个bool变量作为标识,
// 当某种操作完成时设置为true。
bool finished;
// 初始化为false。
finished = false;
// 插入的代码,在这里标识可能被设置为true……细节已省略。
// 测试标识。
if (finished) { // 等同于:if (finished == true) {
Console.WriteLine("完成。");
}
这时,逻辑表达式是响应“是否finished”或“finished是否等于true”的if语句的条件。
!操作符用于否定逻辑表达式,这样,if语句就能在表达式求值为false时执行代码块。
if (!finished) { // 等同于:if (finished == false)
// 如果finished变量被设置为false,这段代码会被执行。
Console.WriteLine("We are not finished。");
}
这时,逻辑表达式是响应“是否未finished”或“finished不等于true”的if语句的条件。
在测试是否相等时,要记得使用两个连续的等于号:
if (x == 3) { // 注意使用双等于号(= =)判断是否相等。
y = x;
}
C#初学者常犯的错误是使用单个等于号测试是否相等:
if (x = 3) {…}
C#中,if判断只能用于有效的逻辑表达式;x=3不是逻辑表达式,而是赋值表达式。
上面的语句甚至根本不能被C#编译器编译,而它却可以被C和C++语言所接受,因为在这些语言里,if测试基于的表达式值为整数0(等同于false)或非0(等同于true)。
可以使用嵌套的if-else构造来测试多个条件。在嵌套使用时,里面的if语句(也许还有else语句)被放置在外面的if语句的else部分中。
两层嵌套的if-else构造基本语法如下所示:
if (condition1) {
// 执行这些代码
}
else {
if (condition2) {
// 执行另外的代码
}
else {
// 如果不满足上述条件,则执行这些代码
}
}
对if-else构造的嵌套层数没有限制。
上例中的嵌套if语句也可以用非嵌套的方式实现:
if (condition1) {
// 执行这些代码
}
else if (condition2) {
// 执行另外的代码
}
else {
// 如果不满足上述条件,则执行这些代码
}
两种形式在逻辑上等同。
下面的例子使用一个嵌套if-else构造,根据员工销售额和服务时间计算奖金额度:
using System;
public class IfDemo
{
static void Main() {
double sales = 40000.0;
int lengthOfService = 12;
double bonus;
if (sales > 30000.0 && lengthOfService >= 10) {
bonus = 2000.0;
}
else {
if (sales > 20000.0) {
bonus = 1000.0;
}
else {
bonus = 0.0;
}
}
Console.WriteLine("Bonus = " + bonus);
}
}
该例程执行结果如下:
Bonus = 2000.0
1.11.2 switch语句
switch语句允许根据条件判断执行一行或多行代码,这与if-else构造相同。不同的是,if-else构造计算一个逻辑表达式的值,而switch语句则拿一个整数或string表达式的值与一个或多个case标签中的值做比较。如果符合其中之一,对应标签后面的代码就会被执行。也可以使用一个可选的default标签,在表达式值不满足任何一个case标签时,执行其后面的代码。
switch语句的一般语法如下:
switch (int-or-string-expression) {
case value1:
// 如果表达式和value1相符,执行这些代码
break;
case value2:
// 如果表达式和value2相符,执行这些代码
break;
// 更多的case标签……
case valueN:
// 如果表达式和valueN相符,执行这些代码
break;
default:
// 如果不满足任何标签,执行默认代码
break;
}
例如:
int x;
// x被赋值,具体细节忽略……
switch (x) {
case 1:
// 伪代码。
do something based on the fact that x equals 1
break;
case 2:
// 伪代码。
do something based on the fact that x equals 2
break;
default:
// 伪代码。
do something based on the fact that x equals something ot her than 1 or 2
break;
}
注意:
l switch关键字后面圆括号中的表达式,其值的类型必须是string或整数。(char、int和long类型都是整数,所以这些类型都可用在switch语句中。)
l case标签后面的值必须是常数(整数、字符或字符串)。
l case和default标签行以冒号而非分号结束。
l 给定case标签后面的语句组,无需用括号包围。它们更像一个语句列表,而不是代码块。
和if语句不同,在满足条件和执行了相应case标签后的代码后,switch语句并不会自动终结。要离开switch语句,必须使用跳出语句(jump statement)——典型的跳出语句是break。如果在任一case标签中没有跳出语句,程序就会继续执行,“贯穿”下一个case或default标签。这种情形可被这样利用:假若多个case标签需要执行相同逻辑,则可将它们堆叠起来:
// 假定x已被声明为int变量
switch (x) {
case 1:
case 2:
case 3:
// 如果x等于1、2或3,执行这些代码
break;
case 4:
//如果x等于4,执行这些代码
}
需要在一系列互斥条件中选择其一时,switch语句非常有用。下例使用switch语句,基于country变量的值,给capital变量赋值。如果没找到匹配结果,则变量被赋值为“not in the database”。
using System;
public class SwitchDemo
{
static void Main() {
string country;
string capital;
country = "India";
// 使用switch语句,拿country变量的值
// 和三个case标签的值进行比较,如果都不符合,
// 执行default标签后面的代码。
switch (country) {
case "england":
capital = "London";
break;
case "India":
capital = "New Delhi";
break;
case "USA":
capital = "Washington";
break;
default:
capital = "not in the database";
break;
}
Console.WriteLine(country + "的首都是" + capital);
}
}
上例输出结果如下:
The capital of India is New Delhi