1、第3章 程序流程控制 本章要点:选择结构及if、switch语句循环结构及循环语句跳出循环异常处理及try-catch-finally语句,3.1 选择结构程序设计,3.1.1 if语句 if语句是最常用的选择语句,它根据布尔表达式的值来判断是否执行后面的内嵌语句。if语句的基本语法格式为:if (布尔表达式) 真值运算;else /可选项假值运算当布尔表达式的值为真,则执行if后面的内嵌语句”真值运算”。为假时执行else后面的内嵌语句“假值运算”。不是所有的if语句都有else匹配,如果仅有if子句则:当布尔表达式为真时执行”真值运算”,否则,当前if语句结束,继续执行if后面的语句。,p
2、ublic static void Main(string args)int x;string y=“;Console.WriteLine(“请输入年龄:“);x = Convert.ToInt32(Console.ReadLine();if (x = 80) y = “耄耋“; /八十、九十曰耄,诗经if (x = 70),如果if或else之后的内嵌语句只包含一条执行语句,则嵌套部分的大括号可以省略,如果包含了两条以上的执行语句,对嵌套部分一定要加上大括号,表示嵌套部分的多条语句为一个语句块,要么全执行要么全不执行。if语句可以嵌套使用,即在判断之中又有判断。 If语句中,如果有else子
3、句,则else与在它前面离它最近且没有其它else与之对应的if相搭配,,public static void Main(string args)int x;string y=“;Console.WriteLine(“请输入以上的年龄:“);x = Convert.ToInt32(Console.ReadLine();if(x = 60)if(x = 70)if(x = 80)y = “耄耋之年“; elsey = “古稀“; elsey = “花甲“; elseif(x = 50)y = “天命“; elsey =“不惑“; Console.WriteLine(“根据年龄推算,你为0之年“,
4、y);,注意:if后的逻辑表达式必须是bool型,using System; class Test static void Main(string args) if (args.Length = 0) Console.WriteLine(“无参数传入“); else Console.WriteLine(“有参数传入“); ,3.1.2 switch语句 if语句只能处理从两者间选择之一,当要实现几种可能之一时,C#语言提供了switch开关语句专门处理多路分支的情形,使程序变得简洁,它的一般格式为:switch(表达式)case value1:内嵌语句块1case value2;内嵌语句块2d
5、efault:内嵌语句块N,3.1.2 switch语句 switch语句的控制类型,即其中控制表达式(expression)的数据类型可以是sbyte、byte、short、ushort、uint、long、ulong、char、string或枚举类型(enum-type)。每个case标签中的常量表达式(value)必须属于或能隐式转换成控制类型,如果有两个或两个以上case标签中的常量表达式值相同,编译时将会报错。switch语句中最多只能有一个default标签。,using System; class Test public static void Main(string args)
6、int x;string y = “;Console.WriteLine(“请输入1000-5000范围内的月收入金额:“);x = Convert.ToInt32(Console.ReadLine();int temp = x/1000;switch(temp)case 5: y = “很优越”; break;case 4: y = “还算舒适”; break;case 3: y = “还不错”; break;case 2: y = “凑合吧”; break;default: y = “要加油工作了”; break;Console.WriteLine(“你月收入0,生活状况为1“,x,y);
7、 ,3.1.2 switch语句 在使用switch语句时有几点需要注意的是:(1) 不允许遍历C和C+语言允许switch语句中case标签后不出现break语句,但C#不允许这样,它要求每个case标签项后使用break语句或跳转语句goto,即不允许从一个case自动遍历到其它case,否则编译时将报错。(2) 允许任意排列switch语句中的case项而不会影响switch语句的执行结果。(3) 每个switch项都以break、goto、case或goto default结束,事实上任何一种不导致“遍历”效果的语句都是允许的。如 throw 和 return 语句同样可以达到不“遍历
8、”。,3.2 循环结构程序设计,3.2.1 for语句 for循环语句是C#中使用频率最高的循环语句,在事先知道循环次数的情况下,使用for循环语句是比较方便的。For循环语句的格式为:for(初始条件;结束条件;循环变量迭代器) 循环体,其中“初始条件”、“结束条件”、“循环变量迭代器”这三项都是可选项。“初始条件”为循环控制变量做初始化,循环控制变量可以有一个或多个(用逗号隔开)。“结束条件”为循环控制条件,也可以有一个或多个语句。“循环变量迭代器”按规律改变循环控制变量的值。初始化、循环控制条件和循环控制都是可选的,如果忽略了条件,则产生一个死循环,要用跳转语句break或goto才能退
9、出。e.g.for (int i=0; i10; i+) Console.WriteLine(i);,3.2.2 foreach语句 foreach语句是在C#中新引入的,它表示遍历一个集合中的各元素,并针对各个元素执行内嵌语句。foreach语句的语法格式为:foreach(type identifier in expression)embedded-statement循环变量由类型type和标识符identifier声明,且表达式expression与集合相对应。循环变量代表循环正在处理的集合元素。在循环体内不能赋一个新值给循环变量,也不能把它当作ref或out参数。,public sta
10、tic void Main()int intArray;intArray = new int5;for (int i = 0; i 5; i+)intArrayi = i;foreach (int i in intArray)Console.WriteLine(i.ToString();Console.ReadLine();,3.2.3 while语句 while语句有条件地将循环体内的语句执行0遍或若干遍。其语法格式为:While (布尔表达式) embedded-statement该语句的执行过程是:(1) 计算布尔表达式布尔表达式的值;(2) 当布尔表达式的值为真时,执行循环体内语句em
11、bedded-statement一遍,程序转至第1步;(3) 直到布尔表达式的值为假时while循环结束。如果首次判断布尔表达式的值即为假,则embedded-statement不被执行。while语句中允许使用break等跳转语句结束循环,执行后续语句;也可以用continue语句来停止内嵌语句的执行,继续进行while循环。,using System; class Test static int Find(int value, int array) int i = 0; while (arrayi != value) if (+i array.Length) Console.WriteLi
12、ne(“当前没有找到!”); return i; static void Main() Console.WriteLine(Find(3, new int 5, 4, 3, 2, 1); ,3.2.4 do-while语句 do-while语句与while语句框架上相似,不同之处在于,它将循环体内的语句至少执行一次。其语法格式为:doembedded-statement while(布尔表达式)该语句按如下顺序执行:(1) 先执行内嵌语句embedded-statement一遍;(2) 计算布尔表达式布尔表达式的值,为true则回到第一步,为false则终止do循环。在do-while循环语句
13、同样允许用break语句和continue语句实现与while语句中相同的功能。无论使用for循环、do循环还是while循环都要小心循环的边界值。它是绝大部分错误的根源,同时要准确判断业务逻辑,正确选择不同的循环类型。,3.2.5 跳出循环 当循环条件不满足时循环自动就结束了,如在循环体内遇到特定的情况需要在循环条件满足的情况下终止循环,就需要用到中断循环语句。C#为此提供了4个命令。分别是:Break:立即终止循环,并跳转到循环后面第一行代码执行Continue:立即终止当次的循环(并不影响循环的继续执行)。Return:用来返回到当前函数被调用的地方。如果return语句放在循环体内,当
14、满足条件时执行return语句返回,循环自动结束 。Goto:可以跳出循环,到已标记好的位置上。,break,using System; class Test public static void Main()int i = 1;for (i = 1 ; i 100 ; i +)Console.WriteLine(i);if (i = 2)break; ,Continue,using System; class Test public static void Main()int i = 99;while(i 0)Console.WriteLine(i);i -;if (i % 2 = 0)i
15、-;elsecontinue;i -; ,return,using System; class Test public static void Ret()Int i = 99;while(i 0)Console.WriteLine(i);i -;if (i =50)return;Public static void Main()Ret();Console.WriteLine(“函数调用结束!“); ,3.3 异常处理结构,3.3.1 异常的产生 C#在两种情况下会产生异常:(1) 在C#语句和表达式的处理过程中激发了某个异常的条件,使得操作无法正常结束,引发异常。 (2) 使用throw语句手
16、动抛掷异常,using System; class Test public static void Main()Console.WriteLine(“enter the number:“);float x=Convert.ToSingle(Console.ReadLine();if(x0)goto less;Console.WriteLine(“Y=1“);goto endpro;less:Console.WriteLine(“Y=-1“);endpro: Console.WriteLine(“End of this program!“); ,using System; class Test
17、public static void Main()Console.WriteLine(“enter the number:“);float x=Convert.ToSingle(Console.ReadLine();if(x0)goto less;Console.WriteLine(“Y=1“);goto endpro;less:Console.WriteLine(“Y=-1“);endpro: throw new Exception(“please enter a number“); ,C#中的System.Exception类是所有异常的基本类型。这个类有几个值得注意的特性,这些特性由所有
18、的异常类共享:Message是一个只读特性,它包含了人们可读的对该异常发生原因的描述。InnerException是一个只读特性,它包含了该异常的“内层异常”。如果它不是null,就表示当前异常是在响应另一个异常时发生的。引起当前异常的那个异常可以在InnerException特性中得到。,3.3.2 处理异常 在代码中对异常进行处理,一般要使用三个代码块:Try块的代码是程序中可能出现错误的操作部分。catch块的代码是用来处理各种错误的部分(可以有多个)。必须正确排列捕获异常的catch子句,范围小的Exception放在前面的catch。即如果Exception之间存在继承关系,就应把子
19、类的Exception放在前面的catch子句中。Finally块的代码用来清理资源或执行要在try块末尾执行的其他操作(可以省略)。且无论是否产生异常,Finally块都会执行。,3.3.2 处理异常 异常是由try_catch_finally语句块组合来处理的,执行异常处理过程通常有以下三种可能的形式:(1) try-catch(s)(2) try-finally(3) try-catch(s)-finally当异常发生时,系统将搜寻最近的能够处理该异常的catch从句,这由异常的运行期类型来决定。首先,在当前方法中搜寻封闭的try语句,按文本顺序考虑与该try语句相关的catch从句。如
20、果无效,就搜寻调用try语句的方法和当前方法,按文本顺序考虑包含调用当前方法的位置的封闭try语句。继续这样的搜寻,直到找到一个能够处理当前异常的catch从句为止。该catch从句命名的异常类与当前异常发生时的运行期类型相同,或者是它的基类。没有命名异常类的catch从句可以处理任何异常。,using System; using System.Collections.Generic; class MainClass static int F(int a, int b) if (b = 0 )throw new Exception(“Divide by zero“);return (a/b);
21、public static void Main( )try /可能出现异常的部分Console.WriteLine(F(5, 0) ); /若第二个实参不为零,则不会抛出异常catch (Exception e) /捕获异常,并进行处理Console.WriteLine(“Error!0“,e.Message);Console.ReadLine(); ,using System; class trycatchfinally public static void Main(string args) long flag = Int64.Parse(args0);int i = 0;int x =
22、3000;int temp = 1;tryif(flag = 1) /如果输入1则抛出除零异常temp= 10/i;else if (flag = 2) /如果输入2则抛出计算溢出docheckedtemp = temp*x;x -;while(x 0);catch(DivideByZeroException DE) /捕获除零异常Console.WriteLine(“除零错误被抛出“);catch(Exception Ex) /捕获其他异常Console.WriteLine(“第二个catch语句“);Console.WriteLine(Ex.Message.ToString();finally /无论是否发生异常,该语句块总被执行Console.WriteLine(“Finally语句块!“); ,