第4章C#流程控制Word格式.docx
《第4章C#流程控制Word格式.docx》由会员分享,可在线阅读,更多相关《第4章C#流程控制Word格式.docx(28页珍藏版)》请在冰点文库上搜索。
![第4章C#流程控制Word格式.docx](https://file1.bingdoc.com/fileroot1/2023-4/29/a1d0dbf1-0c9c-4cce-a82d-3150faadcf37/a1d0dbf1-0c9c-4cce-a82d-3150faadcf371.gif)
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结构就能很好地解决上面程序的问题。
该结构的语法如下:
{语句或语句块}
else
将上一节的代码改为:
Console.Write("
请输入出行月份:
//获得用户输入的出行月份,并转换成整数
=10)//判断出行时间是否在5~10月之间
else//该语句后处理代码是判断条件不满足时进行的处理
淡季出行"
可以看到,代码对两种情况(“旺季”和“淡季”)都作了判断。
对于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成立的处理语句
{语句或语句块}//所有条件都不成立的处理语句
根据这个语句结构,对上面问题可以编写代码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("
amount*0.8);
24.
25.elseif(amount>
=500&
800)
26.{//处理金额在500到800的情形
27.Console.WriteLine("
85%"
28.Console.WriteLine("
amount*0.85);
29.
30.else
31.{//处理金额小于500的情形
32.Console.WriteLine("
90%"
33.Console.WriteLine("
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为假时执行……
}
//表达式1为假时执行……
在这个例子中,假设用1来表示用户选择的头等舱,用2来表示用户选择的经济舱,实现方法如代码4-2所示。
代码4-2嵌套if结构:
NestedIfExample.cs
6.namespaceNestedIfExample
8.classProgram
12.intprice=2000;
//机票的原价
13.intmonth;
//出行的月份
14.inttype;
//头等舱为1,经济舱为2
16.Console.WriteLine("
请输入您出行的月份:
1-12"
17.month=int.Parse(Console.ReadLine());
请问您选择头等舱/经济舱?
头等舱输入1,经济舱输入2"
19.type=int.Parse(Console.ReadLine());
if(month>
=5&
month<
=10)//旺季
21.{
22.if(type==1)//头等舱
23.{
24.Console.WriteLine("
您的机票价格为:
price*0.9);
25.}
26.elseif(type==2)//经济舱
27.{
price*0.75);
29.}
30.}
31.
else//淡季
32.{
33.if(type==1)//头等舱
34.{
35.Console.WriteLine("
price*0.6);
37.elseif(type==2)//经济舱
38.{
39.Console.WriteLine("
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;
……
default:
语句n;
进行比较的表达式可以是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="
4.stringcountry=”China”;
5.stringlauguange=”Chinese”;
6.switch(country)
8.caseengland:
9.casebritain:
//这里将会产生一个编译错误
10.language="
English"
11.break;
12.}
在编译上面代码的时候,会有错误提示消息:
标签“case"
”已经出现在该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
6.namespaceWhileExample
8.classWhileExample
11.
12.while(true)
13.{
14.Console.Write("
请输入'
高兴'
的英文单词:
15.//获得用户输入的单词,并删除首尾空格
16.stringvol=Console.ReadLine().Trim();
17.//判断输入单词是否为happy,不区分大小写
18.if(vol.ToUpper()=="
HAPPY"
)
19.{//如果输入正确,跳出循环
恭喜你,输入正确"
21.break;
22.}
23.else
24.{//如果输入不正确,继续执行循环
25.Console.WriteLine("
输入错误,请重新输入!
26.}
27.}
28.Console.ReadLine();
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{语