C#程序设计案例教程 第3章 程 序 结 构
学习目标 知识目标 技能目标 自学内容 掌握顺序结构的用法。 掌握选择结构的用法。 掌握循环结构的用法。 通过循环结构创建游戏网格,学会循环结构的使用。 通过GDI+画出蛇和食物,学会分支结构if语句的使用。 通过对键的控制,学会分支结构switch语句的使用。 自学内容 如何通过在窗体类中覆写(重写)ProcessDialogKey()方法判断按键。 如何通过在窗体类中覆写(重写)OnPaint()方法实现动画效果。
开 场 白 最近流行一则幽默:一直觉得《西游记》有个BUG,唐僧肉吃完长生不老,那他为什么不咬自己一口?咬完各路妖魔奈我何?轻装上路差旅费省四分之三。后来想明白了,觉得吴承恩设计得真周密——和尚不能吃肉。
原来吴承恩在整个小说里设置了一个如下判断: 如果(对象==和尚) {不能吃肉();} 其他 { 如果(对象吃到唐僧肉) 原来吴承恩在整个小说里设置了一个如下判断: 如果(对象==和尚) {不能吃肉();} 其他 { 如果(对象吃到唐僧肉) {长生不老();} }
小说不能平铺直叙,好的小说除了有顺叙,总还会有倒叙和插叙。正是这些不同的结构才使得小说情节跌宕起伏、峰回路转。编写程序和写小说一样,要通过不同结构来处理各种事务。
3.1 顺序与选择结构 3.1.1 基础知识 3.1.1.1 if语句 1.简单的if语句,提供一种选择,语法如下: if(条件) 3.1 顺序与选择结构 3.1.1 基础知识 3.1.1.1 if语句 1.简单的if语句,提供一种选择,语法如下: if(条件) {语句序列} //当满足条件,就执行(语句序列),否则跳过if语句,执行if语句后面的程序
2.if-else语句,提供两种选择,语法如下: {语句序列1} //当满足条件时执行 else {语句序列2} //当不满足条件时执行
3.else if语句,提供多种选择,语法如下: {语句序列n+1} //当所有条件都不满足时执行
3.1.1.2 switch语句 switch(表达式) { case 可能性的值1: 语句序列1 [break;] 语句序列2 … [default: //还可以加任意一个:case可能性的值:语句序列 break; 语句序列n+1 break;] }
3.1.2 案例说明——淘宝积分 1.案例情境 淘宝会员买家积分达到一定数额,系统则会自动升级 至相应等级。如1000分以下的买家等级为V0, 1000~5000(不含5000)买家等级为V1,5000~ 20000(不含20000)买家等级为V2,20000分以上 为V3,如图3.1所示。现根据描述编写程序,输入积分, 则显示当前等级。程序运行结果如图3.2所示。
图3.2 程序Example3-1的运行结果 图3.1 淘宝会员买家积分与等级
4.代码及分析 static void Main(string[] args) { float credit; //定义积分变量 Console.WriteLine("亲,请输入您的当前积分:"); credit = float.Parse(Console.ReadLine()); if (credit >= 20000) Console.WriteLine("您为V3会员!"); else if (credit >= 5000) Console.WriteLine("您为V2会员!"); else if (credit >= 1000) Console.WriteLine("您为V1会员!"); else if (credit >= 0) Console.WriteLine("您为V0会员!"); else Console.WriteLine("亲,您准在开玩笑!"); Console.ReadLine(); }
用switch语句来实现 case 'c': speaking="您为V1会员!"; break; } string speaking; if (credit >=20000) c='a'; else if (credit >= 5000) c='b'; else if (credit >= 1000) c='c'; else if (credit >= 0) c='d' else c='e' switch(c) { case 'a': speaking="您为V3会员!"; break; case 'b: speaking="您为V2会员!"; break; case 'c': speaking="您为V1会员!"; break; case 'd': speaking="您为V0会员!"; break; case 'e': speaking="亲,您准在开玩笑!";break; } Console.WriteLine(speaking) ;
3.2 选择结构的窗体应用 3.2.1 基础知识 3.2.1.1 单选控件 1.常用属性 2.常用事件 3.2.1.2 复选控件
3.2.2 案例——网上选购 案例情境 本案例将设计一个顾客选购商品的系统。其中顾客身份有两类:一类是VIP,另一类是普通会员。商品种类有4种,分别是手套、骑行音箱、骑行鞋和青蛙灯。其中VIP享受9折优惠和商店赠送的礼品,而普通会员都不享受。单击【确定】按钮后,系统根据顾客不同的选择,在文本框显示顾客最终的选购结果。顾客默认身份为普通会员。
图3.3 添加控件后的效果
3.3 while和do-while循环 3.3.1 基础知识 3.3.1.1 while语句 3.3.1 基础知识 3.3.1.1 while语句 while语句先计算表达式的值,值为true则执行循环体,反复执行上述操作,直到表达式的值为false时止。 语法如下: while(表达式) { 循环体 }
3.3.1.2 do-while语句 do-while语句先执行循环体语句一次,再判别表达式的值,若为true则继续循环,否则终止循环。 语法如下: do{ 循环体 }while(表达式)
3.3.2 案例——外星文明的信号 案例情境 “浩瀚的宇宙中如果只有我们的话,岂不是太浪费地方?” 科幻电影《接触未来》的女主角埃莉收到了来自外太空的信号,从而开启正式接触外星文明之旅。起初天外来音代表的是最朴素的数学语言,即一组素数/质数。因为一组有顺序的质数不可能是自然随机产生的,所以可以肯定是外星文明发出的。 本案例要求模仿外星文明产生200以下的素数,如2,3,5,7,11,13…
static void Main(string[] args) { int i=2, j = 0; while (i < 200) j=2; while (j <= Math.Sqrt(i)) //对于每一个数i,从2开始对其求余,直到根号i结束 if (i % j == 0) //如果求余结果为0,则为不是质数 break; //跳出内循环 j++; } if (j > Math.Sqrt(i)) //如果j大于根号i,则表明是质数 Console.Write(i + "\t"); i++; Console.ReadLine();
3.4 for循环 3.4.1 基础知识 for语句和while语句一样,也是一种循环语句,用来重复执行一段代码。两个循环语句的区别就是使用方法不同。 for语句的使用语法如下: for(表达式1;表达式2;表达式3) { 循环体 }
2.使用break/continue控制循环 在while和for循环语句中,如果满足条件,则循环会一直继续下去,那么该如何自动控制循环的中断和继续呢? C#提供了break/continue语句,用来控制循环的执行。break可以中断当前正在执行的循环,并跳出整个循环。continue表示中断当前本次的循环,其后面的代码无须执行,并进行下一次表达式的计算与判断,以决定是否重新开始下一次循环。break语句还可以和switch语句配合使用,在达到某种条件时从switch语句跳出。
3.4.2 案例——黄金分割 案例情境 建筑师们对数学0.618…特别偏爱,无论是古埃及的金字塔,还是巴黎圣母院,或者是法国的埃菲尔铁塔,都有与0.618…有关的数据。人们还发现,一些名画、雕塑、摄影作品的主题,大多在画面的0.618…处。艺术家们认为弦乐器的琴马放在琴弦的0.618…处,能使琴声更加柔和甜美。 斐波那契数列(Fibonacci Sequence)又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、…即Fn=F(n-1)+F(n-2)。 斐波那契数列与黄金分割有什么关系呢?经研究发现,相邻两个斐波那契数的比值是随序号的增加而逐渐趋于黄金分割比的。即F(n)/F(n+1)≈0.618。当继续计算出后面更大的斐波那契数时,就会发现相邻两数之比确实是非常接近黄金分割比的。 斐波那契数列又因数学家斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”。一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么40个月以后可以繁殖多少对兔子?
我们可推出下表 经过月数 1 2 3 4 5 6 7 8 9 10 11 12 幼仔对数 13 21 34 55 89 成兔对数 144 总体对数 233
程序 static void Main(string[] args) { int f1 = 1, f2 = 1, f; //第1、2个月都只有1对 int month; double GoldenSection; for (month = 3; month <= 40;month++ ) //从第3个月起开始计算 f = f1 + f2; f1 = f2; f2 = f; } GoldenSection=0.1*f1/f2; //整型转为双精度型 Console.WriteLine("第{0}个月后共有{1}对兔子\n", month - 1, f2); //求出40个月后兔子总数 Console.WriteLine("f1={0},f2={1}\nf1/f2={2}", f1, f2, GoldenSection); //求出黄金比例
3.5 贪吃蛇项目分解——结构与键控 3.5.1 任务描述 本节我们要利用本章所学的分支结构、循环结构,画出“贪吃蛇”游戏相关画面,让大家看到贪吃蛇的真面目。本节任务如下: (1)画出格子表示游戏区域。 (2)根据蛇身长度参数,在游戏区域中央画好蛇。 (3)在定点位置画出食物。 (4)在按下“开始新游戏”按钮后,能实现对按键的判断功能。 界面设计如图3.7所示。
图3.7 贪吃蛇的真面目
3.6 本 章 小 结 C#程序设计中有三大程序结构,分别为顺序结构、选择结构和循环结构。顺序结构是由一系列的语句所构成的,其中任何一条语句都会被执行一次,而且执行的顺序是由程序的第一行一直执行到结束为止。选择结构可以让程序在执行时能够根据不同的条件选择不同的语句执行,选择的标准是根据指定的条件是否成立。循环结构是在给定条件成立时,反复执行某循环体,直到条件不成立为止。 本章通过几个案例介绍了选择结构中的if语句、switch语句,循环结构中的while语句、do-while语句、for语句,以及break与continue语句的用法以及它们之间的区别。