第4章C#流程控制.docx
- 文档编号:20253638
- 上传时间:2023-04-25
- 格式:DOCX
- 页数:28
- 大小:175.75KB
第4章C#流程控制.docx
《第4章C#流程控制.docx》由会员分享,可在线阅读,更多相关《第4章C#流程控制.docx(28页珍藏版)》请在冰豆网上搜索。
第4章C#流程控制
第4章流程控制
程序设计流程是指程序中程序语句的执行顺序。
多数情况下,程序中的语句是按顺序执行的,但是,光有顺序结构的程序,所能解决的问题是有限的,于是就出现了复杂的流程结构。
1966年Bohm和Jacopini证明,任何解题程序的流程都可以由图4.1所示的3种流程结构——顺序结构、选择(分支)结构和循环结构构成。
在这一章,主要介绍选择结构和循环结构的机制。
通过本章学习,读者将了解以下内容:
❑使用条件结构实现程序逻辑。
❑使用循环结构实现程序逻辑。
❑实现复杂的程序逻辑。
❑理解和使用程序调试。
图4.1程序流程的3种基本结构
4.1条件判断——选择的艺术
C#提供了三种类型的选择结构。
选择语句可以根据条件是否成立,或根据表达式的值控制代码的执行分支。
C#有两个基本分支代码的结构:
if选择结构,测试特定条件是否满足,在条件为真时,执行操作,否则跳过操作;switch语句,比较表达式和许多不同的值,根据表达式的值进行特定处理。
4.1.1分支选择:
if语句
if结构称为单选择结构。
C#继承了C和C++的if结构。
其语法结构很直观,如下所示:
if(条件)
{
//将执行的语句或语句块
}
如果指定的条件成立,则执行大括号里的语句。
否则,跳过该语句继续执行。
在上面的if语句的条件判断中,会用到比较值的C#运算符。
这里要注意,与C/C++一样,C#里使用“==”对变量进行比较,而不能使用“=”,“=”用于赋值。
如果在条件中要执行多条语句,可以将这多条语句用花括号({})组合为一个语句块。
这也适用于其他可以将语句组合成语句块的结构。
先面暑假到了,Kenrome和Landy一家决定外出旅行,他们要在网上预定机票。
机票的价格根据出行时间是否为旺季,所打的折扣是不同的。
网上订票系统要根据用户输入的出行月份,判断是否为旺季(5到10月)出行,如果是,则提示“旺季出行”,以便于用户确认,这时,模拟实现这一功能的代码如下:
Console.WriteLine("请输入出行月份(1-12):
");
intmon=int.Parse(Console.ReadLine());//获得用户输入的出行时间,并转换成整数
if(mon>=5&&mon<=10)
Console.WriteLine("旺季出行");
注意:
与C++不同,C#中的if语句不能直接测试整数,而必须明确在把整数转换成为布尔值true或false。
这段代码在执行过程中,会让用户输入一个出行月份,然后根据用户的输入进行判断是否是旺季出行。
这段代码的执行流程如图4.2所示。
图4.2if结构执行流程
读者可能会发现这个问题,如果输入的月份不在5~10月之间,程序就没有任何输出提示。
这是因为,程序段里没有对不在5~10月间的数据进行处理的代码。
那么,如果游客在其他月份出行,在程序运行中也会出现提示信息该怎么解决呢。
这就要用到下一小节的分支结构if-else。
4.1.2if-else结构
上面的网上订票系统还不完善,它只做出了对用户输入出行时间是旺季的提示,而kenrome一家如果选择出行的时间是淡季,系统将不会有任何提示。
这时,kenrome会想,是不是系统出问题了,为什么没有提示确认信息?
实际上,上面代码没有对用户选择出行时间表淡季的提示。
if-else结构也是用于分支结构设计的,和if结构相比,它多了对指定条件不满足的处理代码,即else语句后的代码或代码块。
用if-else结构就能很好地解决上面程序的问题。
该结构的语法如下:
if(条件)
{语句或语句块}
else
{语句或语句块}
将上一节的代码改为:
Console.Write("请输入出行月份:
");
intmon=int.Parse(Console.ReadLine());//获得用户输入的出行月份,并转换成整数
if(mon>=5&&mon<=10)//判断出行时间是否在5~10月之间
Console.WriteLine("旺季出行");
else//该语句后处理代码是判断条件不满足时进行的处理
Console.WriteLine("淡季出行");
可以看到,代码对两种情况(“旺季”和“淡季”)都作了判断。
注意:
对于if语句,如果条件分支中只有一条语句,可以不用花括号,但是为了保持一致,许多程序员只要使用if语句,就会加上花括号。
else后的语句就是在if指定条件不成立的情况下的处理代码。
如果kenrome一家选择的出行月份是8,则程序运行效果如图4.3所示。
图4.3程序运行结果
4.1.3多重if结构
【本节示例参考:
\源代码\chapter4\4.1.3\MultiIfExample】
通过上两小节的学习,读者会发现,不管是哪种类型的选择结构,都只能对一个条件进行判断,那如果判断的条件不只一个,该如何解决?
比如下面的例子:
某网上书店售书,根据一次性的购买金额有不同的折扣率。
假设金额高于1000,则打75折,800~1000打8折,500~800打85折,小于500是9折。
要求根据用户输入的购书金额,计算折扣后的价格。
像这种对多个条件的判断,可以用多重if结构来解决。
该语句的语法格式如下:
if(条件1)//判断条件1是否成立
{语句或语句块}//条件1成立的处理语句
elseif(条件2)//条件1不成立的情况下,判断条件2是否成立
{语句或语句块}//条件2成立的处理语句
else
{语句或语句块}//所有条件都不成立的处理语句
根据这个语句结构,对上面问题可以编写代码4-1所示的程序。
代码4-1多重if结构:
MultiIfExample.cs
1.usingSystem;
2.usingSystem.Collections.Generic;
3.usingSystem.Linq;
4.usingSystem.Text;
5.
6.namespaceMultiIfExample
7.{
8.classMultiIfExample
9.{
10.staticvoidMain(string[]args)
11.{
12.Console.Write("请输入你的购书金额:
");
13.//将用户输入的金额转换成float型数据
14.floatamount=float.Parse(Console.ReadLine());
15.
if(amount>=1000)
16.{//处理金额大于1000的情形
17.Console.WriteLine("折扣为:
75%");
18.Console.WriteLine("你应付的书款为:
{0}",amount*0.75);
19.}
20.
elseif(amount>=800&&amount<1000)
21.{//处理金额在800到1000的情形
22.Console.WriteLine("折扣为:
80%");
23.Console.WriteLine("你应付的书款为:
{0}",amount*0.8);
24.
}
25.elseif(amount>=500&&amount<800)
26.{//处理金额在500到800的情形
27.Console.WriteLine("折扣为:
85%");
28.Console.WriteLine("你应付的书款为:
{0}",amount*0.85);
29.
}
30.else
31.{//处理金额小于500的情形
32.Console.WriteLine("折扣为:
90%");
33.Console.WriteLine("你应付的书款为:
{0}",amount*0.9);
34.}
35.Console.ReadLine();
36.}
37.}
38.}
注意:
添加到if子句中的elseif语句的个数没有限制。
假设用户输入的购书金额为650元,这时程序的运行结果如图4.4所示。
图4.4程序运行结果
4.1.4嵌套if结构
【本节示例参考:
\源代码\chapter4\4.1.4\NestedIfExample】
看下面机票预定的例子。
假设机票原价是2000,根据用户输入的出行季节以及选择的是头等舱还是经济舱,折扣不同,5~10月为旺季,头等舱打9折,经济舱打7.5折,其他时间为淡季,头等舱打6折,经济舱打3折。
这个例子中,一次订票过程会有两次判断:
一是对出行季节的判断,一是对选择舱位的判断。
这就要用到嵌套if结构,即在if判断里面又嵌入if判断块。
嵌套if的语法格式如下:
if(表达式1)
{
if(表达式2)
{
//表达式2为真时执行……
}
else
{
//表达式2为假时执行……
}
}
else
{
//表达式1为假时执行……
}
在这个例子中,假设用1来表示用户选择的头等舱,用2来表示用户选择的经济舱,实现方法如代码4-2所示。
代码4-2嵌套if结构:
NestedIfExample.cs
1.usingSystem;
2.usingSystem.Collections.Generic;
3.usingSystem.Linq;
4.usingSystem.Text;
5.
6.namespaceNestedIfExample
7.{
8.classProgram
9.{
10.staticvoidMain(string[]args)
11.{
12.intprice=2000;//机票的原价
13.intmonth;//出行的月份
14.inttype;//头等舱为1,经济舱为2
15.
16.Console.WriteLine("请输入您出行的月份:
1-12");
17.month=int.Parse(Console.ReadLine());
18.Console.WriteLine("请问您选择头等舱/经济舱?
头等舱输入1,经济舱输入2");
19.type=int.Parse(Console.ReadLine());
20.
if(month>=5&&month<=10)//旺季
21.{
22.if(type==1)//头等舱
23.{
24.Console.WriteLine("您的机票价格为:
{0}",price*0.9);
25.}
26.elseif(type==2)//经济舱
27.{
28.Console.WriteLine("您的机票价格为:
{0}",price*0.75);
29.}
30.}
31.
else//淡季
32.{
33.if(type==1)//头等舱
34.{
35.Console.WriteLine("您的机票价格为:
{0}",price*0.6);
36.}
37.elseif(type==2)//经济舱
38.{
39.Console.WriteLine("您的机票价格为:
{0}",price*0.3);
40.}
41.}
42.Console.ReadLine();
43.}
44.}
45.}
当用户输入的出行月份是5月,选择经济舱的时候,运行效果如图4.5所示。
图4.5程序运行结果
4.1.5多路选择:
switch语句
【本节示例参考:
\源代码\chapter4\4.1.5\SwitchExample】
switch-case语句适合从一组互斥的分支中选择一个执行。
其形式是switch语句后面跟一组case子句。
如果switch参数中表达式的值等于某个case子句旁边的某个值,就执行该case子句的代码,此时不需要使用花括号把语句组合到语句块中,只需要在每个case语句的结尾使用break标记表示结束。
也可以在switch语句中包含一个default语句,如果表达式不等于任何case子句的值,就执行default子句的代码。
基本语法格式如下:
switch(int/char/string表达式)
{
case常量表达式1:
语句1;
break;//必须有
case常量表达式2:
语句2;
break;//必须有
……
default:
语句n;
break;//必须有
}
注意:
进行比较的表达式可以是int型,char型和string型。
case的值必须是常量表达式,不允许使用变量值。
例如下面的例子,用户输入今天是星期几,然后根据用户的输入进行判断。
假设只判断星期六和星期天,其余显示为“工作日”,实现代码如下:
1.strings=Console.ReadLine();//定义一个字符串变量,获得控制台输入
2.switch(s)//分支判断
3.{
4.case"saturday":
//第一种情况
5.Console.WriteLine("今天是星期六");
6.break;
7.case"sunday":
//第二种情况
8.Console.WriteLine("今天是星期天");
9.break;
10.default:
//默认情况
11.Console.WriteLine("今天是工作日");
12.break;
13.}
在C#中,switch语句的一个有趣的地方是case语句的排放顺序是无关的,甚至可以把default语句放在最前面。
在C#中使用switch结构有以下注意事项。
❑条件判断的表达式类型可以是整型或字符串,这是与C++里的switch语句的一个不同之处,在C++里,是不允许用字符串作测试变量的。
❑每个case子句都有break标记
❑default子句也要有break标记
❑case中没有其他语句时,可以不需要break语句,程序则执行下一个case
❑每个case都不能相同。
这包括值相同的不同常量,如下面的编码方式就是不正确的:
1.//assumecountryisoftypestring
2.conststringengland="uk";
3.conststringbritain="uk";
4.stringcountry=”China”;
5.stringlauguange=”Chinese”;
6.switch(country)
7.{
8.caseengland:
9.casebritain:
//这里将会产生一个编译错误
10.language="English";
11.break;
12.}
在编译上面代码的时候,会有错误提示消息:
标签“case"uk":
”已经出现在该switch语句中。
4.2程序调试——重过程更重结果
有时候程序并不能按照我们预期的效果执行;有时候本认为程序是对的,但结果是错误的。
最让程序员感到头痛的是不知道程序错在哪里?
调试就能帮助解决这个问题。
VS2008也提供了很好的调试工具,本节就主要学习如何进行调试。
4.2.1VisualStudio2008中的调试
程序调试就是在开发过程中,通过某种手段,让程序员跟踪程序执行过程,了解程序执行细节,以便于开发完整的能达到预期效果的程序。
VisualStudio2008中的调试规则和以前的版本没有太大区别,通过设置断点和查看变量值,以便在程序执行过程中检查某处发生的情况。
4.2.2设置断点
在VisualStudio2008中,可以在执行的代码中给任意一行设置断点(breakpoint)。
断点的作用是通知调试器应在某点上中断应用程序,并暂停执行。
可以在代码编辑器中的文档窗口左侧的阴影区域单击该行,或是选择该行,按下F9键,设置一个断点,只要代码执行到断点处,就会中断,把控制权交给调试程序。
在VisualStudio2008中,断点在代码编辑器中用该行左边的一个大圆表示,如图4.6所示。
VisualStudio会把设置了断点的行及其背景用另一种颜色突出显示。
再次单击该圆,就会删除断点。
如果程序并不是想每次运行到断点处都停止,可以设置条件断点。
读者可以通过在VisualStudio2008菜单栏中选择“调试”“窗口”“断点”命令,打开“断点设置”对话框,如图4.7所示。
图4.6断点用一个红色圆表示图4.7断点设置窗口
如果在程序中设置了不只一个断点,所有的断点都会罗列在这里。
可以通过右键单击将要设置条件的断点,在右键菜单上选择将要进行的操作。
在右键菜单上选择“条件”选项,弹出“断点条件”对话框,如图4.8所示。
用户可以在对话框里给相关变量设置断点条件。
也可以指定在对设置的断点代码执行一定次数后,或是执行某行代码一定次数后,才中断程序执行。
这时可以在上述右键菜单上选择“命中次数”选项,弹出如图4.9所示的对话框。
图4.8断点条件对话框图4.9断点命中次数对话框
4.2.3跟踪调试
当遇到断点时,通常要查看变量的值,最简单的方式是在代码编辑器中,把鼠标指针停放在某一变量上,查看在断点时刻该变量的值,如图4.10所示。
当程序运行到断点处时,在代码编辑器中,把鼠标指针停放在str6上,会显示一个小方框,方框中给出了变量的值。
图4.10监视变量在断点时的值
也可以通过监视窗口查看变量的值。
监视(watch)窗口主要用于查看计算变量和表达式的值。
调试器提供了很多变量窗口,这些窗口用于显示、计算和编辑变量与表达式。
每个变量窗口都是网格窗口,其中包含三列:
“名称”、“值”和“类型”。
“名称”列包含变量名称或表达式。
“值”和“类型”列显示变量或表达式的值和数据类型,如图4.11所示。
显示在网格中的信息类型取决于正在使用的变量窗口。
图4.11监视窗口
“局部变量”窗口显示,对于当前上下文或范围来说位于本地的变量。
通常,这是当前正在执行的过程或函数,调试器自动填充此窗口。
在VisualC#中,如果禁用了异常助手,一旦出现活动异常,则“局部变量”窗口还会显示伪变量$exception。
可以展开该伪变量以查看异常的详细信息。
“自动”窗口显示在当前代码行和上一代码行中使用的变量。
对于本机C++,“自动”窗口还显示函数返回值。
与“局部变量”窗口类似,“自动”窗口是由调试器自动填充的。
在“监视”窗口中可以添加要监视其值的变量。
此外,还可以添加变量以外的其他内容。
可以添加调试器所能识别的任何有效表达式。
(有关有效表达式语法,请参见:
调试器中的表达式)。
某些版本的VisualStudio有多个“监视”窗口,其编号为“监视1”到“监视4”。
“快速监视”对话框在概念上类似于“监视”窗口,但是“快速监视”每次只能显示一个变量或表达式。
如果需要快速查看变量或表达式,而不想打开“监视”窗口,则可以使用“快速监视”功能。
但是,很多用户会发现新增强的数据提示功能强大,以至于用户越来越少地使用到“快速监视”功能。
4.3循环——解决重复的工作
C#提供了4种循环机制:
for、while、do…while和foreach。
循环的作用简单理解就是在满足某个条件之前,可以重复执行代码块。
for、while、do…while和C/C++里的循环相同。
4.3.1检票员的工作:
while语句
【本节示例参考:
\源代码\chapter4\4.3.1\WhileExample】
while语句的作用是执行一个语句,直到指定的条件为false。
换句话说,当指定条件成立时,程序会重复执行循环体里的语句。
可以将while语句的作用类比作现实生活中的检票员。
不管我们是去看电影还是去游乐场,都要检票进入。
检票员的工作就是循环检票,不到最后一个观众或游客,不遇到意外情况,就会不停检票放行。
while语句的语法如下:
while(条件)
{语句或语句块}
while语句在循环的每次迭代前检查的布尔表达式。
如果条件是true,则执行循环,如果是false,则该循环永远不执行。
while语句一般用于一些简单重复的工作,这也是计算机擅长的。
另外和将要讲到的for语句相比,while语句可以处理事先不知道要重复多少次的循环。
比如代码4-3所示,要求用户一直输入“高兴”的英文单词,直到输入正确为止。
代码4-3while语句:
WhileExample.cs
1.usingSystem;
2.usingSystem.Collections.Generic;
3.usingSystem.Linq;
4.usingSystem.Text;
5.
6.namespaceWhileExample
7.{
8.classWhileExample
9.{
10.staticvoidMain(string[]args)
11.
{
12.while(true)
13.{
14.Console.Write("请输入'高兴'的英文单词:
");
15.//获得用户输入的单词,并删除首尾空格
16.stringvol=Console.ReadLine().Trim();
17.//判断输入单词是否为happy,不区分大小写
18.if(vol.ToUpper()=="HAPPY")
19.{//如果输入正确,跳出循环
20.
Console.WriteLine("恭喜你,输入正确");
21.break;
22.}
23.else
24.{//如果输入不正确,继续执行循环
25.Console.WriteLine("输入错误,请重新输入!
");
26.}
27.}
28.Console.ReadLine();
29.}
30.}
31.}
上述代码运行结果如图4.12所示。
图4.12程序运行结果
在上面程序中,由于事先不知道用户要输入多少次才能输入正确的单词,所以用了while循环,并且,循环条件设置为true,能够保证一直循环让用户输入单词。
那读者可能会有疑问,如果用户输入正确,就应该终止循环,这又是怎么实现的呢?
终止循环的关键就在于break语句。
该语句的详细讲解,请参考后续章节。
4.3.2赛跑的艺术:
do-while语句
【本节示例参考:
\源代码\chapter4\4.3.2\DoWhileExample】
do-while语句重复执行括在{}的一个语句或语句块,直到指定的表达式计算为false。
与while语句不同的是,do-while循环会在计算条件表达式之前执行一次。
在本章图4.1中,循环结构有两种,其中图中左边的一种循环结构是while语句,而右边的流程是do-while语句。
do-while语句的语法如下:
do{语
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 流程 控制