1、学习情境三学习情境三 控控 制制 流流 程程 3.1 任务一:选择控制流程任务一:选择控制流程 3.2 任务二:任务二:while循环语句的应用循环语句的应用 3.3 任务三:任务三:for循环的基本应用及嵌套循环的基本应用及嵌套 3.4 任务四:任务四:for循环在数组上的应用循环在数组上的应用 3.5 举一反三举一反三 3.1 任务一:选择控制流程任务一:选择控制流程3.1.1 功能描述功能描述判断某年某月的天数:本程序从控制台接受用户输入的年份和月份,判断该年该月的天数并输出。该判断包括大小月的判断和闰年的判断。通过该任务,我们应学会:选择语句的实现。选择语句包括if语句和switch语
2、句两种,它们能够根据实际情况选择要执行的代码。使用嵌套的if语句和switch语句。3.1.2 代码展示代码展示1 using System;2 namespace ConsoleApplication53 4 class Program5 6 static void Main(string args)7 8 int year,month,day=0;9 Console.WriteLine(*请输入年份,回车确认*);10 year=Int32.Parse(Console.ReadLine();11 Console.WriteLine(*请输入月份,回车确认*);12 month=Int32.
3、Parse(Console.ReadLine();13 if(year10000)14 Console.WriteLine(*您输入的年份不合理!*);15 else if(month 12)16 Console.WriteLine(*您输入的月份不合理!*);17 else18 19 switch(month)20 21 case 1:22 case 3:23 case 5:24 case 7:25 case 8:26 case 10:27 case 12:day=31;break;28 case 4:29 case 6:30 case 9:31 case 11:day=30;break;3
4、2 case 2:33 if(year%400=0)|(year%4=0)&(year%100!=0)34 day=28;35 else36 day=29;37 break;38 39 Console.WriteLine(*该月份的天数为 0 天*,day);40 41 Console.ReadKey();42 43 44 代码分析:912从控制台请求用户输入年份和月份,并保存在整型变量year和month中。1416判断用户输入的年月值是否合理,若不合理,给出提示信息。17 这个else语句是嵌套的if语句的最后一个情况,也就是当年月的值都合理时,才能执行到这个else所带的语句块。2038
5、 这是一个多分支的switch语句,通过判断month的值来确定该月是大月还是小月,大月是31天,小月是30天。2月是个特殊情况,需要判断是否闰年来决定是28还是29天。将判断得到的天数存放到变量day中。39 输出变量day的值。41 该行用于让程序停住,等待用户输入任意键继续。也就是我们前面讲到过的,便于查看程序运行结果。3.1.3 知识点知识点1if语句语句条件选择语句用来判断所给定的条件是否满足,根据判断结果真(true)或假(false),决定执行一种选择。一般说来,判断条件以关系表达式或逻辑表达式的形式出现。条件选择根据选择结构主要分成单分支选择、双分支选择和嵌套选择。单分支结构的
6、语法如下:if(表达式)语句块一;语句块二;该结构先判断表达式的值,若表达式值为真,则执行语句块一;否则跳过语句块一,执行语句块二。程序流程图如下:在该结构中,语句块二是if单分支结构的后续语句,实际上无论表达式判断结构如何,语句块二都会被执行。双分支结构的语法如下:if(表达式)语句块一;else 语句块二;该结构先判断表达式的值,若表达式值为真true,则执行语句块一;否则(表达式的值为假false)执行语句块二。程序流程图如下:在这种结构中,语句一和语句二只有一段会被执行到,不可能都被执行。3.1.4 知识点知识点2嵌套的嵌套的if语句语句作为if语句执行结果的语句可以是另外一个if语句
7、。也就是说,上文中的“语句块一”、“语句块二”本身又可以是另一个if语句。这种情况称为嵌套的if语句。嵌套的if语句用来处理复杂的判断条件。例如,以下代码段用来根据货品数量和规格修改库存。1 if(number 0)2 if(size=7)3 size7Num+=number;/size7Num表示规格为7的货品的库存值4 else/otherNum表示其它规格的货品的库存值5 otherNum+=number;6 else 7 Console.WriteLine(已无库存!);第1行和第6行是一对if语句。第2行到第5行又是一对if语句,它们是第1行的if语句所嵌套的。当库存数量number
8、大于0时,需要再判断规格size是否等于7,再作不同处理。当程序逻辑中出现类似于此的复杂判断时,就需要根据实际情况进行嵌套。3.1.5 知识点知识点3switch语句语句switch语句是一种多分支语句。在嵌套使用if语句时,所有if语句看起来都非常相似,因为它们都在对一个完全相同的表达式进行求值。当每个if语句都将表达式的结果与一个不同的值进行比较时,通常可将嵌套的if语句改写为一个switch语句,这样会使程序更有效,更易懂。例如:if(day=0)dayName=Sunday;else if(day=1)dayName=Monday;else if(day=2)dayName=Tuesd
9、ay;else if(day=3).else dayName=Unknown;以上代码块中,判断条件都很类似:day=0、day=1、day=2、day=3等,可以将其改写成以下代码:switch(day)case 0:dayName=Sunday;break;case 1:dayName=Monday;break;case 2:dayName=Tuesday;break;case 3:dayName=Tuesday;break;default:dayName=Unknown;break;显然,switch语句在处理这类问题时更为方便。switch语句的语法形式如下:switch(表达式)ca
10、se常量表达式1:语句;break;case常量表达式2:语句;break;case常量表达式3:语句;break;case 常量表达式n:语句;break;default:语句;break;其语义为:计算表达式的值,从表达式值等于某常量表达式值的case开始,它下方的所有语句都会一直运行,直到遇到一个break为止。随后,switch语句将结束,忽略其它case,程序从switch结束大括号之后的第一个语句继续执行。使用switch语句的注意事项:(1)case标签和后续语句之间用冒号“:”隔开。(2)在C#中,各个case语句和default语句的次序可以打乱,并不影响执行结果。(3)只能
11、针对基本数据类型使用switch,这些类型包括int和string等。对于其它类型,则必须使用if语句。(4)case标签必须是常量表达式,如42或者42。如果需要在运行时计算case标签的值,则必须使用if语句。(5)case标签必须是唯一性的表达式。也就是说,不允许两个case具有相同的值。(6)可以连续写下一系列case标签(中间不能间插额外的语句),从而指定自己希望在多种情况下都运行相同的语句。如果像这样写,那么最后一个case标签之后的代码将适用于该系列的所有case。(7)对于有关联语句的case标签,语句结束后必须有break语句,否则编译器会报错。错误说明通常为“控制不能从一个
12、case标签(“case:”)贯穿到另一个case标签”,如图3.1所示。图3.1 3.2 任务二:任务二:while循环语句的应用循环语句的应用3.2.1 功能描述功能描述名片夹:本例实现一个控制台名片夹,该程序运行时在用户屏幕上显示一列可供选择的选项,用户通过键盘输入选择不同的字符以选择进入对应的子功能。除此之外,该程序还用循环语句实现用户的重复选择。通过本任务,我们应当掌握:循环语句while、do-while的使用。循环语句允许多次重复执行一行或一段代码。跳转语句break、continue、goto、return的使用。跳转语句允许在程序中进行跳转,增加程序的灵活性。3.2.2 代码
13、展示代码展示1 using System;2 namespace ConsoleApplication63 4 class Program5 6 static void Main(string args)7 8 string myChoice;9 do 10 Console.WriteLine(My Address Bookn);11 Console.WriteLine(A-Add New Address);12 Console.WriteLine(D-Delete Address);13 Console.WriteLine(M-Modify Address);14 Console.Write
14、Line(V-View Addresses);15 Console.WriteLine(Q-Quitn);16 Console.WriteLine(Choice(A,D,M,V,orQ):);17 myChoice=Console.ReadLine();18 switch(myChoice)19 20 caseA:21 casea:22 Console.WriteLine(You wish to add an address.);23 /此处可以加入“添加地址”的代码方法函数 24 break;25 caseD:26 cased:27 Console.WriteLine(You wish to
15、 delete an address.)28 /此处可以加入“删除地址”的代码方法函数29 break;30 caseM:31 casem:32 Console.WriteLine(You wish to modify an address.);33 /此处可以加入“修改地址”的代码方法函数34 break;35 caseV:36 casev:37 Console.WriteLine(You wish to view the address list.);38 /此处可以加入“查看地址列表”的代码方法函数39 break;40 caseQ:41 caseq:42 Console.WriteLi
16、ne(Bye.);break;43 default:44 Console.WriteLine(0 is not a valid choice,myChoice);45 break;46 47 Console.Write(Press any key to continue.);48 Console.ReadLine();49 while(myChoice!=Q&myChoice!=q);50 51 52 代码分析:8 定义一个字符串类型的变量myChoice,用于保存用户输入的选项。9 do-while语句的开始,到45行是循环体。表示只要45行的while语句所带的表达式为真,就始终执行循环体
17、。1016 打印可选项17 保存用户的选项。将用户选择的选项保存在变量myChoice中。2042 根据用户输入的选项,选择不同的case语句来执行不同选项对应的代码块。可以将代码块写成方法放在另一个类中。4346 对用户的非法输入进行处理。48 退出前停留在用户屏幕,以便用户查看运行结果。49 若用户没有退出,则继续请求输入。程序将回到第10行再次执行。3.2.3 知识点知识点1while语句语句while语句可以在一个布尔表达式为true的前提下重复运行一个语句块。其语法如下:while(布尔表达式)语句块;while语句先判断布尔表达式的值,若表达式的值为真,则执行循环体语句。执行完循环
18、体语句后回到表达式继续判断,直到表达式的值为假(false),跳过循环体,结束while循环。流程图如下:例如,以下代码计算x的阶乘,将结果保存在变量y中:y=1;while(x!=0)y*=x;x-;3.2.4 知识点知识点2do-while语句语句do-while语句与while语句不同的是,它将内嵌语句执行至少一次。其语法如下:do 语句块;while(布尔表达式);do-while语句先执行内嵌语句块一遍,然后计算布尔表达式的值,若为真(true)则回到do继续执行,为false则终止do循环。语句流程图如下:例如,计算x的阶乘,写成do-while循环如下:long y=1;do y
19、*=x;x-;while(x0)3.2.5 知识点知识点3跳转语句:跳转语句:break、continue、goto及时有效的跳转有助于提升程序的执行效率。及时有效的跳转有助于提升程序的执行效率。1.breakbreak语句用于终止最近的封闭循环或它所在的switch语句,控制传递给终止语句后面的语句(如果有的话)。(1)break语句只能用在switch 语句或循环语句中,其作用是跳出switch语句或跳出本层循环,转去执行后面的程序。由于break语句的转移方向是明确的,所以不需要语句标号与之配合。(2)break语句的一般形式如下:break;(3)使用break语句可以使循环语句有多个
20、出口,在一些场合下使编程更加灵活、方便。例如:for(i=1;i=5;i+)if(i=3)break;Console.Write(i);当i等于3时,控制跳出for循环中break后面的语句,所以,该语句段的执行结果为:12 2.continuecontinue语句将控制权传递给它所在的封闭迭代语句的下一次迭代。(1)continue语句只能用在循环体中,其一般格式如下:continue;其语义是:结束本次循环,即不再执行循环体中continue语句之后的语句,转入下一次循环条件的判断与执行。(2)语句只结束本层本次的循环,并不跳出循环。例如:for(i=1;i=5;i+)if(i=3)con
21、tinue;Console.Write(i);当i等于3时,控制跳过for循环中continue后面的语句,所以,该语句段的执行结果为:1245 3.gotogoto语句将程序控制直接传递给标记语句。(1)goto的一个通常用法是将控制传递给特定的switch-case标签或switch语句中的默认标签。其一般格式如下:goto 语句标号;其中语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto语句配合使用,如:label:i+;loop:while(x7);(2)goto语句还用于跳出深嵌套循环。C#语言不限制程序中使用标号的次数,
22、但规定各标号不得重名。goto语句的语义是改变程序流向,转去执行语句标号所标识的语句。goto语句通常与条件语句配合使用。可用来实现条件转移,构成循环、跳出循环体等功能。但是,在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,给理解和调试程序带来困难。3.3 任务三:任务三:for循环的基本应用及嵌套循环的基本应用及嵌套3.3.1 功能描述功能描述在在1.5节中,我们曾要求读者通过控制台,用最基本的输出语节中,我们曾要求读者通过控制台,用最基本的输出语句输出一个由句输出一个由“*”组成的菱形。那么,如果要求读者输出一个组成的菱形。那么,如果要求读者输出一个有有50行的大菱形
23、,是否也要一行一行地输出呢?本任务就解决了行的大菱形,是否也要一行一行地输出呢?本任务就解决了这个问题。这个问题。用用“*”输出各种大小的菱形:本任务通过两个嵌套的输出各种大小的菱形:本任务通过两个嵌套的for循循环,在用户屏幕上输出一个由环,在用户屏幕上输出一个由“*”号和空格组成的菱形,菱形号和空格组成的菱形,菱形大小由定义的符号常量控制。大小由定义的符号常量控制。通过本任务,我们应学会:通过本任务,我们应学会:for循环的简单应用;循环的简单应用;使用嵌套的使用嵌套的for循环处理复杂的情况。循环处理复杂的情况。3.3.2 代码展示代码展示1 using System;2 namespa
24、ce Diamond3 4 class Program5 6 static void Main(string args)7 8 const int MAX_ROWS=8;9 int row,star;10 for(row=1;row=MAX_ROWS;row+)11 12 for(int i=0;i=(MAX_ROWS-row);i+)13 Console.Write();14 for(star=1;star=1;row-)19 20 for(int i=0;i=(MAX_ROWS-row);i+)21 Console.Write();22 for(star=1;star=row;star+)
25、23 Console.Write(*);24 Console.WriteLine();25 26 Console.Read();27 28 29 代码分析:8 定义符号常量MAX_ROWS,用来控制菱形的大小。这里MAX_ROWS的值为8,表示菱形的上三角有8行。如果需要改变菱形的大小,只需修改MAX-ROWS的值即可1017 设计菱形的上三角。外层for循环每循环一次,完成菱形的一行的绘制。1213 该循环控制每行的空格数。越靠上的行空格越多。1415该循环控制每行“*”的数量。本例中输出的菱形上三角中,第n行的星号数量为n个。故为了对齐,输出星号时实际上输出的是星号和空格(“*”)。注意:
26、不输出空格也可以输出完整的菱形,请读者自行完成。16 换行输出。1825 输出下三角。算法和上三角一样,只是个数控制上有所区别。3.3.3 知识点知识点1for语句语句for语句的一般形式为:for(式1;式2;式3)for语句的语义为:(1)计算表达式1的值。(2)计算表达式2的值,若值为真(非0)则执行循环体一次,否则跳出循环。(3)计算表达式3的值,转回第(2)步重复执行。注意:在整个for循环过程中,表达式1只计算一次,表达式2和表达式3则可能计算多次。循环体可能多次执行,也可能一次都不执行。3.3.4 知识点知识点2嵌套的循环嵌套的循环循环体里面也可以有循环,这就是所谓的循环嵌套。内
27、部循环在外部循环体中。在外部循环的每次执行过程中都会触发内部循环,直到内部循环执行结束。外部循环执行了多少次,内部循环就完成多少次。当然,无论是内部循环还是外部循环的break语句,都会打断处理过程。循环嵌套可以解决很多问题,经常被用于按行列方式输出数据。例如,以下程序段用于输出九九乘法表:int i,j;for(i=1;i=9;+i)/外循环控制输出多少行 for(j=1;j=i;+j)/内循环控制输出多少列 Console.Write(0,i*j);/输出乘积 Console.WriteLine();/换行 3.4 任务四:任务四:for循环在数组上的应用循环在数组上的应用3.4.1 功能
28、描述功能描述冒泡排序算法:该任务为冒泡排序算法,通过嵌套的for循环实现。该算法通过两两比较,每次循环都将最小的数“冒”到顶端。若共有n个数,则通过n-1次循环即可完成递增排序。3.4.2 代码展示代码展示1 using System;2 namespace ConsoleApplication13 4 class Program5 6 static void Main(string args)7 8 int Array=3,27,1,99,36,52,1,77,9,7;9 for(int i=0;i Array.Length;i+)10 11 for(int j=i+1;j Arrayj)1
29、4 15 int temp=Arrayi;16 Arrayi=Arrayj;17 Arrayj=temp;18 19 20 21 foreach(int k in Array)22 23 Console.WriteLine(k);24 25 Console.Read();26 27 28 代码分析:8 定义并初始化一个10个元素的一维整型数组。920 外重for循环,从数组的第一个元素循环到最后一个。1119 内嵌的for循环,从外重for循环当前所在的数组元素循环到数组的最后一个元素。外重循环第一次时,将数组的第一个元素与其它元素比较大小,若第一个元素比后面的元素大,则交换它们的位置。这样一
30、次循环下来,最小的元素就“浮”到第一个上面了。以此类推,第n次外重循环就将剩下元素的最小值“浮”到第n个位置上。2124 用一个foreach循环输出排序后的数组元素。3.4.3知识点知识点1C#的数组的数组1.一维数组一维数组 一维数组以线性方式存储固定数目的项,只需一个索引值即可标识任意一个项。在C#中,数组声明中的方括号必须跟在数据类型后面,且不能放在变量名称之后,而这在许多其它语言中是允许的。例如,整型数组应使用以下语法声明:int arr1;下面的声明在C#中无效:int arr2;声明数组后,可以使用new关键字设置其大小。下面的代码声明数组引用:int arr;arr=new i
31、nt5;/声明一个5元素整型数组然后,可以使用“数组名索引值”访问一维数组中的元素。C#数组索引是从0开始的。也就是说,第一个元素是“数组名0”。下面的代码访问上面数组中的最后一个元素:Console.WriteLine(arr4);/输出第5个元素2.一维数组的初始化一维数组的初始化 C#数组元素可以在创建时进行初始化:int arr2;arr2=new int5 1,2,3,4,5;初始值设定项的数目必须与数组大小完全匹配。可以使用此功能在同一行中声明并初始化C#数组:int arr1Line=1,2,3,4,5;此语法创建一个数组,其大小等于初始值设定项的数目。在C#中初始化数组的另一个
32、方法是使用for循环。下面的循环将数组的每个元素都设置为0:for(int i=0;iTaxRates.Length;i+)arr2i=0;3.多维数组多维数组 可以使用C#创建规则的多维数组(数组的数组),多维数组类似于同类型值的矩阵。使用以下语法声明多维矩形数组:int,arr2D;/二维数组 float,arr4D;/四维数组 声明之后,可以按如下方式为数组分配内存:arr2D=new int8,6;/声明一个8行6列的二维数组然后,可以使用以下语法访问数组的元素:arr2D4,2=906;由于数组是从零开始的,因此此行将第5行第3列中的元素设置为906。4.二维数组初始化二维数组初始化
33、 可以使用以下几种方法之一在同一个语句中创建、设置并初始化多维数组:int,arr4=new int 2,3 1,2,3,4,5,6;int,arr5=new int,1,2,3,4,5,6;int,arr6=1,2,3,4,5,6;3.4.4 知识点知识点2foreach语句语句foreach语句是在C#中新引入的,C和C+中没有这个语句,它表示收集一个集合中的各个元素,并针对各个元素执行内嵌语句。foreach语句的格式为:foreach(type identifier in collection)其中,类型(type)和标识符(identifier)用来声明循环变量,集合名称(colle
34、ction)也可以是数组或者简单地是一个字符串。foreach每执行一次内嵌语句,循环变量就依次取collection中的一个元素代入其中。在这里,循环变量是一个只读型局部变量,试图改变它的值将引发编译时的错误。回想一下,假设Array是一个一维数组的名称,则将Array遍历一遍的for语句代码是:for(int i=0;i Array.Length;i+)Console.WriteLine(Arrayi);如果用foreach语句呢?foreach语句让我们跳过循环初始化,不必指定索引,只需知道集合的类型即可。例如Array是一个浮点型float的数组,则遍历代码如下:foreach(flo
35、at k in Array)Console.WriteLine(k);3.4.5 知识点知识点3调试:监视窗口调试:监视窗口在学习情境一的调试部分,我们学习了“局部变量窗口”,它列出了当前执行的方法的所有变量。如果有很多变量,则这个变量列表将会很长,这给我们查找某个特定变量造成不便。“监视窗口”为我们观察特定变量提供了便利。在程序暂停后,在局部变量窗口中右击变量名选择“添加监视”,将变量加入到“监视窗口”中。在“监视窗口”中,我们可以像在“局部变量窗口”中一样进行修改。也就是说,除了可以选择特定的变量来观察外,“监视窗口”和“局部变量窗口”是一样的。要从“监视窗口”中移除一个变量,可以右击变量
36、所在行的任何地方,选择“删除监视”。要删除所有变量,可以右击窗口,选择“全选”,然后再右击,选择“删除监视”或按Delete键。3.5 举举 一一 反反 三三1.某百货公司为了促销,采用以下购物打折的办法。a.消费金额1000元(含)以上者,按九五折优惠;b.消费金额2000元(含)以上者,按九折优惠;c.消费金额3000元(含)以上者,按八五折优惠;d.消费金额5000元(含)以上者,按八折优惠。(1)编写程序,输入购物款数,计算并输出优惠后的价格。(要求用switch语句编写。)(2)将该程序写成可连续输入多个款额的形式。即:可以多次获取用户的数据,输出对应的值,无需重启程序。2.编写一个应用程序,要求从控制台输入两个整数,求两个数的最小公倍数并输出。3.定义一个一维数组,循环从控制台读取数据给数组元素。输出数组的最大值。4.将一张一百元的钞票换成一元、二元、五元的零钱,要正好换50张。编程计算总共有几种换法。要求输出每一种换法的详情及换法总数。