c# 课堂总结7--函数

函数:
数据类型-变量类型-运算符号表达式-语句(顺序,分支,循环)-数字

程序里的函数:能完成一个相对独立功能的代码块。
数学里的函数:高度抽象。
函数四要素:函数名,输入(参数),输出(返回值类型),加工(函数体)

函数定义:
[static]返回类型 函数名(输入参数列表)
{
//函数体-加工
}

函数调用:
[数据类型 变量名]=函数(参数);
函数名(参数);---用于无返回类型的函数
数据类型 变量=函数名(参数);---用于有返回类型的函数

1.参数匹配
在调用函数时,调用的参数和函数定义的参数保持一对待:个数,类型,对应。

形参:形式参数。--函数定义的参数。
实参:实际参数。--函数调用的参数。

实参、形参传值的规律--传址,传值。
传值:鉴于整型、浮点、bool、char这几种内建函数传递参数的时候,默认都是传值。
传值是把实参做一个副本(copy)传递给形参。
m=30;
Add(m);
static void Add(int a)
{
a+=20;
}
传址:默认情况下,数组就是传地址。字符串也是传地址。
对于内建的整型、浮点、bool、char这些类型,如果要变成传址的话,需要在前面加ref
m=30;
Add(ref m);
static void Add(ref int a)
{
a+=20;
}
对于传值和传址大家要记住:
1.什么是传值,什么传址?这个要分清楚。
2.默认情况下,哪些类型传值?哪些类型传址?
3.对于默认传值的类型,如何让他们变为传址?ref

以后为了防止因为传值、传址引起的错误,建议采用返回值的形式,明确返回的数据。

例题部分

 1         eg.1 传值的方法
 2         static void Main(string[] args)
 3         {
 4             int m = 30;
 5             Console.WriteLine("Main函数第一次打印:"+m);//30
 6             Add(m);
 7             Console.WriteLine("Main函数第二次打印:" + m);//30
 8         }
 9         static void Add(int a)
10         {
11             Console.WriteLine("Add函数第一次打印:"+a);//30
12             a += 20;
13             Console.WriteLine("Add函数第二次打印:"+a);//50
14         }
15 
16 
17         eg.2 传址方式,加ref
18         static void Mainb(string[] args)
19         {
20             int m = 30;
21             Console.WriteLine("Main函数第一次打印:" + m);//30
22             Add1( m);
23             Console.WriteLine("Main函数第二次打印:" + m);//30
24             Console.WriteLine("Main函数第三次打印:" + m);//30
25             Add2(ref m);
26             Console.WriteLine("Main函数第四次打印:" + m);//50
27         }
28 
29         static void Add1(int a)
30         {
31             Console.WriteLine("Add1传值函数第一次打印:" + a);//30
32             a += 20;
33             Console.WriteLine("Add1传值函数第二次打印:" + a);//50
34         }
35 
36         static void Add2(ref int a)
37         {
38             Console.WriteLine("Add2传址函数第一次打印:" + a);//30
39             a += 20;
40             Console.WriteLine("Add2传址函数第二次打印:" + a);//50
41         }
42 
43         eg.3 传址与传值 数组名 传址,数组元素传值。
44         static void Main1(string[] args)
45         {
46             int[] m = new int[4] {3,5,7,9 };
47 
48             //打印原值
49             foreach (int a in m)
50             {
51                 Console.Write(a+"\t");
52             }
53 
54             //调用函数,传递整个数组
55             Add(m);//传得是数组名,传的是地址。
56 
57             Add9(m[2]);//传得是数组的某个元素,是传值。
58             //打印改变后的值
59             foreach (int a in m)
60             {
61                 Console.Write(a+"\t");
62             }
63         }
64 
65         static void Add9(int a)
66         {
67             Console.WriteLine("Add9被调用了,在Add9中把传进来的" + a + "变成了" + a * 100);
68             a = a * 100;
69         }
70 
71         static void Add(int[] b)
72         {
73             for (int i = 0; i < b.Length; i++)
74             {
75                 b[i] *= 10;
76             }
77         }
View Code

2、函数重载?

在函数重载时,应包括函数签名的所有方面,例如,有两个不同的函数,他们分别值参数和引用参数。
static void ShowDouble(ref int val)
{
....
}

static void ShowDouble(int val)
{
....
}

选择使用哪个版本纯粹是根据是否包含ref关键字来确定的,下面的代码将调用引用版本:
ShowDouble(ref val);
下面的代码将调用值版本:
ShowDouble(val);
另外还要根据参数的个数来区分函数。

3、委托。

eg.1 对战改 函数

 

  1 //人人对战
  2    
  3 
  4     class class1
  5     {
  6         static void Mainmydemo5(string[] args)
  7         {
  8             string[] jn=new string[10];//return 与out 的区别 :out 返回值时,不用规定数组的大小,return返回值是,数组必须创建出多大的。eg买东西!
  9             //int[] sh=new int[10];
 10             int[] sh;
 11             jn = JiNeng(jn, out sh);//数组默认就是传址,不需要加ref,但有的时候不同
 12 
 13             //string[] jn;
 14             //int[] sh;
 15             //JiNeng(out jn, out sh);
 16 
 17             player p1=new player();
 18             player p2=new player();
 19             ShuRu(ref p1.name, ref p2.name);
 20 
 21             //攻击方数据输出
 22             p1 = PlayerPeiZhi(jn, sh, p1);
 23             PlayerPeiZhiShuChu(p1);
 24 
 25             //防守方数据输出
 26             p2 = PlayerPeiZhi(jn, sh, p2);
 27             PlayerPeiZhiShuChu(p2);
 28             
 29             //战斗开始
 30             Console.WriteLine("→→→→→→→→→");
 31 
 32             Console.WriteLine("请按空格键开始对战");
 33             ConsoleKeyInfo key = Console.ReadKey();
 34             Console.Clear();
 35 
 36             if (key.Key.ToString().ToLower() == "spacebar")
 37             {
 38                 while (true)
 39                 {
 40                     #region 战斗开始
 41                     //攻击方攻击
 42                     ZhanDou(ref p1, ref p2);
 43 
 44                     Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
 45 
 46 
 47 
 48                     //退出循环的判断!
 49                     bool m = TuiChu(ref p1, ref p2);
 50                     if (m)
 51                     {
 52                         break;
 53                     }
 54                     else
 55                     {
 56 
 57                     }
 58 
 59 
 60                     //防守方攻击
 61                     ZhanDou(ref p2, ref p1);
 62 
 63                     Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
 64 
 65                    
 66                     
 67                     //退出循环的判断!
 68                     bool n = TuiChu(ref p1, ref p2);
 69                     if (n)
 70                     {
 71                         break;
 72                     }
 73                     else
 74                     {
 75 
 76                     }
 77                     #endregion
 78 
 79                     Thread.Sleep(2000);
 80                 }
 81             }
 82         }
 83 
 84 
 85 
 86         /// <summary>
 87         /// 输出玩家的配置
 88         /// </summary>
 89         /// <param name="t">形参 玩家</param>
 90         private static void PlayerPeiZhiShuChu(player t)
 91         {
 92             player a = new player();
 93             a = t;
 94             Console.WriteLine("攻击方的战斗力如下:");
 95             Console.WriteLine("姓名:" + a.name + ",血量:" + a.blood + ",攻击力:" + a.attack + ",防御力:" + a.defence + ",闪避力:" + a.shanbi);
 96             Console.WriteLine("技能1为:{0},技能2为:{1},技能3为{2} 。", a.jineng[0], a.jineng[1], a.jineng[2]);
 97         }
 98 
 99 
100 
101         /// <summary>
102         /// 判断退出条件
103         /// </summary>
104         /// <param name="a">玩家1的信息</param>
105         /// <param name="b">玩家2的信息</param>
106         /// <returns>为 真 则退出,为 假 则继续。</returns>
107         private static bool TuiChu(ref player a, ref player b)
108         {
109             bool c;
110             if (b.blood == 0)
111             {
112                 Console.WriteLine(a.name + "" + b.name + "KO!");
113                 c = true;
114                 //break;
115             }
116             else if (a.blood == 0)
117             {
118                 Console.WriteLine(b.name + "" + a.name + "KO!");
119                 c = true;
120                 //break;
121             }
122             else if (a.blood == 0 && b.blood == 0)
123             {
124                 Console.WriteLine("平局!");
125                 c = true;
126                 //break;
127             }
128             else
129             {
130                 c = false;
131             }
132             return c;
133         }
134 
135 
136         /// <summary>
137         /// 战斗开始
138         /// </summary>
139         /// <param name="p1">玩家1的信息</param>
140         /// <param name="p2">玩家2的信息</param>
141         private static void ZhanDou(ref player a, ref player b)
142         {
143             //普通攻击
144             Random m1 = new Random();
145             //int a1 = m1.Next(3);
146             if (b.shanbi >= m1.Next(12))
147             {
148                 Console.ForegroundColor = ConsoleColor.Yellow;
149                 Console.WriteLine(a.name + "" + b.name + "使用普通攻击,但被" + b.name + "躲过了。");
150                 Console.ForegroundColor = ConsoleColor.Red;
151                 //Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood); Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
152                 //Thread.Sleep(1000);
153             }
154             else
155             {
156                 b.blood = b.blood - a.attack + b.defence;
157                 Console.ForegroundColor = ConsoleColor.Black;
158                 Console.WriteLine(a.name + "使用普通攻击,对" + b.name + "造成了" + (a.attack - b.defence) + "点伤害。");
159                 Console.ForegroundColor = ConsoleColor.Red;
160                 if (b.blood <= 0)//判断是否为负血量,如果为<0,则让他=0,自己做的时候没想到
161                 {
162                     b.blood = 0;
163                 }
164                 //Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
165                 //Thread.Sleep(1000);
166             }
167 
168             //技能攻击
169             Random m2 = new Random();
170             int a1 = m2.Next(3);
171             if (m2.Next(2) >= m2.Next(10))
172             {
173                 Console.ForegroundColor = ConsoleColor.Blue;
174                 Console.WriteLine(a.name + "释放了" +a.jineng[a1] + ",对" + b.name + "造成了" + a.shanghai[a1] + "伤害。");
175                 b.blood = b.blood - Convert.ToInt32(a.shanghai[a1]);
176                 Console.ForegroundColor = ConsoleColor.Red;
177                 if (b.blood <= 0)//判断是否为负血量,如果为<0,则让他=0,自己做的时候没想到
178                 {
179                     b.blood = 0;
180                 }
181                 //Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
182                 //Thread.Sleep(1000);
183             }
184         }//用ref 的目的就是传的a,b的地址这样才能够输出a,b因为战斗而改变的数据
185 
186 
187         /// <summary>
188         /// 战斗力配置
189         /// </summary>
190         /// <param name="jn">选择3个技能</param>
191         /// <param name="sh">对应出3个技能的伤害</param>
192         /// <param name="p1">对应的玩家</param>
193         /// <returns>返回玩家配置</returns>
194         private static player PlayerPeiZhi(string[] jn, int[] sh, player p)
195         {
196             int seed1 = 0;
197             if (p.name.Length == 2)
198             {
199                 seed1 = (int)(Convert.ToChar(p.name.Substring(0, 1))) + (int)(Convert.ToChar(p.name.Substring(1, 1)));
200             }
201             else if (p.name.Length == 3)
202             {
203                 seed1 = (int)(Convert.ToChar(p.name.Substring(0, 1))) + (int)(Convert.ToChar(p.name.Substring(1, 1))) +
204                     (int)(Convert.ToChar(p.name.Substring(2, 1)));
205             }
206             Random r1 = new Random(seed1);
207 
208             p.blood = r1.Next(501) + 3500;//血量
209             p.attack = r1.Next(51) + 250;//攻击力
210             p.defence = r1.Next(21) + 100;//防御力
211             p.shanbi = r1.Next(2) + 2;//闪避
212             p.jineng = new ArrayList();//具体到当前p1.jineng这样集合。把结构体里的jineng类面对p1创建出p1.jineng的对象。
213             p.shanghai = new ArrayList();
214 
215             //技能+伤害
216             for (int i = 0; i < 3; i++)
217             {
218                 Random q = new Random();
219                 int a = q.Next(10);
220                 if (!p.jineng.Contains(jn[a]))
221                 {
222                     p.jineng.Add(jn[a]);
223                     p.shanghai.Add(sh[a]);
224                 }
225                 else
226                 {
227                     i--;
228                 }
229             }
230 
231             return p;
232         }
233 
234 
235         /// <summary>
236         /// 技能及伤害
237         /// </summary>
238         /// <param name="jn">技能</param>
239         /// <param name="sh">伤害</param>
240         private static string[] JiNeng(string[] jn,out int[] sh)//或者static void JiNeng(out string[] jn, out int[] sh)
241         {
242 
243             jn = new string[10] { "横扫千军", "釜底抽薪", "降龙十巴掌", "雷霆一击", "死亡一指", "紧箍咒", "五雷轰顶", "装嫩", "卖萌", "青年2B打法" };
244             sh = new int[10] { 300, 350, 351, 311, 280, 350, 300, 280, 300, 300 };
245             return jn;
246         }
247 
248 
249         /// <summary>
250         /// 输入姓名
251         /// </summary>
252         /// <param name="a">玩家1</param>
253         /// <param name="b">玩家2</param>
254         private static void ShuRu(ref string a, ref string b)//此处错误,因为a,b传的是值 
255         {
256             Console.WriteLine("请输入出战方的姓名:");
257             a = Console.ReadLine();
258             Console.WriteLine("请输入防守方的姓名:");
259             b = Console.ReadLine();
260         }
261 
262         //private static void ShuRu(string a, string b)//此处错误,因为a,b传的是值 
263         //{
264         //    Console.WriteLine("请输入出战方的姓名:");
265         //    a = Console.ReadLine();
266         //    Console.WriteLine("请输入防守方的姓名:");
267         //    b = Console.ReadLine();
268         //}
269 
270     }
View Code

 

eg.2 推箱子 

  1  #region eg 1  推箱子
  2 
  3 
  4         static void Main1(string[] args)
  5         {
  6             int a = 1;
  7             while (true)
  8             {
  9                 int[,] map = new int[10, 10];
 10                 map = Map(a);
 11 
 12                 MapDisplay(map);
 13 
 14                 int x = ZuoBiao(map, 1, 1);
 15                 int y = ZuoBiao(map, 1, 2);
 16                 int r = ZuoBiao(map, 2, 1);
 17                 int s = ZuoBiao(map, 2, 2);
 18                 while (map[r, s] != 2)
 19                 {
 20                     ConsoleKeyInfo key = Console.ReadKey();
 21 
 22                     #region 向右走
 23                     if (key.Key.ToString() == "RightArrow")
 24                     {
 25                         if (y < 8)//右移最大不会超过y=8坐标
 26                         {
 27                             if (map[x, y + 1] == 0)//人的下一步只能是空地,或箱子,或墙,或终点,先判断空地
 28                             {
 29                                 map[x, y + 1] = 1;
 30                                 map[x, y] = 0;
 31                                 //走过终点后,再让终点恢复出来!
 32                                 //if (a[8, 8] != 2)
 33                                 //    a[8, 8] = 3;
 34                                 if (map[r, s] != 2)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
 35                                     map[r, s] = 3;
 36                                 //if (a[8, 6] != 2)
 37                                 //    a[8, 6] = 3;
 38                                 y++;
 39 
 40                             }
 41                             else if (map[x, y + 1] == 3)//人的下一步是终点
 42                             {
 43                                 map[x, y + 1] = 1;
 44                                 map[x, y] = 0;
 45                                 y++;
 46                             }
 47                             else if (map[x, y + 1] == 2 && map[x, y + 2] == 0)//人的下一步是箱子
 48                             {
 49                                 map[x, y + 1] = 1;
 50                                 map[x, y + 2] = 2;
 51                                 map[x, y] = 0;
 52 
 53                                 //if (a[8, 8] != 2 && a[8, 8] != 1)
 54                                 //    a[8, 8] = 3;
 55                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
 56                                     map[r, s] = 3;
 57                                 //if (a[8, 6] != 2 && a[8, 6] != 1)
 58                                 //    a[8, 6] = 3;
 59 
 60                                 y++;
 61                             }
 62                             else if (map[x, y + 1] == 2 && map[x, y + 2] == 3)//人的下一步是箱子,箱子的下一步是终点
 63                             {
 64                                 map[x, y + 1] = 1;
 65                                 map[x, y + 2] = 2;
 66                                 map[x, y] = 0;
 67 
 68                                 //if (a[8, 8] != 2)
 69                                 //    a[8, 8] = 3;
 70                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
 71                                     map[r, s] = 3;
 72                                 //if (a[8, 6] != 2)
 73                                 //    a[8, 6] = 3;
 74 
 75                                 y++;
 76                             }
 77                             else //其中包括,人的下一步是墙,箱子的下一步是墙
 78                                 Console.WriteLine("\a");
 79                         }
 80                         else
 81                             Console.WriteLine("\a");
 82                     }
 83                     #endregion
 84 
 85                     #region 向左走
 86                     if (key.Key.ToString() == "LeftArrow")
 87                     {
 88                         if (y > 1)//左移最小不会小于y=1坐标
 89                         {
 90                             if (map[x, y - 1] == 0)//人的下一步只能是空地,或箱子,或墙,先判断空地
 91                             {
 92                                 map[x, y - 1] = 1;
 93                                 map[x, y] = 0;
 94 
 95                                 //if (a[8, 8] != 2)
 96                                 //    a[8, 8] = 3;
 97                                 if (map[r, s] != 2)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
 98                                     map[r, s] = 3;
 99                                 //if (a[8, 6] != 2)
100                                 //    a[8, 6] = 3;
101                                 y--;
102                             }
103                             else if (map[x, y - 1] == 3)
104                             {
105                                 map[x, y - 1] = 1;
106                                 map[x, y] = 0;
107                                 y--;
108                             }
109                             else if (map[x, y - 1] == 2 && map[x, y - 2] == 0)//人的下一步是箱子
110                             {
111                                 map[x, y - 1] = 1;
112                                 map[x, y - 2] = 2;
113                                 map[x, y] = 0;
114 
115                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
116                                     map[r, s] = 3;
117 
118                                 y--;
119                             }
120                             else if (map[x, y - 1] == 2 && map[x, y - 2] == 3)//人的下一步是箱子,箱子的下一步是终点
121                             {
122                                 map[x, y - 1] = 1;
123                                 map[x, y - 2] = 2;
124                                 map[x, y] = 0;
125 
126                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
127                                     map[r, s] = 3;
128 
129                                 y--;
130 
131                             }
132                             else //其中包括,人的下一步是墙,箱子的下一步是墙
133                                 Console.WriteLine("\a");
134                         }
135                         else
136                             Console.WriteLine("\a");
137                     }
138                     #endregion
139 
140                     #region 向上走
141                     if (key.Key.ToString() == "UpArrow")
142                     {
143                         if (x > 1)//上移不能超过x=8坐标
144                         {
145                             if (map[x - 1, y] == 0)//人的下一步只能是空地,或箱子,或墙,先判断空地
146                             {
147                                 map[x - 1, y] = 1;
148                                 map[x, y] = 0;
149 
150                                 //if (a[8, 8] != 2)
151                                 //    a[8, 8] = 3;
152                                 if (map[r, s] != 2)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
153                                     map[r, s] = 3;
154                                 //if (a[8, 6] != 2)
155                                 //    a[8, 6] = 3;
156 
157                                 x--;
158                             }
159                             else if (map[x - 1, y] == 3)//人下一步是终点,走上去的时候照样替换,走之后,就是人下一步是空地的问题了
160                             {
161                                 map[x - 1, y] = 1;
162                                 map[x, y] = 0;
163                                 x--;
164                             }
165                             else if (map[x - 1, y] == 2 && map[x - 2, y] == 0)//人的下一步是箱子,箱子的下一步是空地
166                             {
167                                 map[x - 1, y] = 1;
168                                 map[x - 2, y] = 2;
169                                 map[x, y] = 0;
170 
171                                 //if (a[8, 8] != 2 && a[8, 8] != 1)
172                                 //    a[8, 8] = 3;
173                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
174                                     map[r, s] = 3;
175                                 //if (a[8, 6] != 2 && a[8, 6] != 1)
176                                 //    a[8, 6] = 3;
177 
178                                 x--;
179                             }
180                             else if (map[x - 1, y] == 2 && map[x - 2, y] == 3)//人的下一步是箱子,箱子的下一步是终点
181                             {
182                                 map[x - 1, y] = 1;
183                                 map[x - 2, y] = 2;
184                                 map[x, y] = 0;
185 
186                                 //if (a[8, 8] != 2)
187                                 //    a[8, 8] = 3;
188                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
189                                     map[r, s] = 3;
190                                 //if (a[8, 6] != 2)
191                                 //    a[8, 6] = 3;
192 
193                                 x--;
194                             }
195                             else //其中包括,人的下一步是墙,箱子的下一步是墙
196                                 Console.WriteLine("\a");
197                         }
198                         else
199                             Console.WriteLine("\a");
200                     }
201                     #endregion
202 
203                     #region 向下走
204                     if (key.Key.ToString() == "DownArrow")
205                     {
206                         if (x < 8)//下移不能超过x=8坐标,只能下走增大,给个上限就可以
207                         {
208                             if (map[x + 1, y] == 0)//人的下一步只能是空地,或箱子,或墙,先判断空地
209                             {
210                                 map[x + 1, y] = 1;
211                                 map[x, y] = 0;
212                                 //if (a[8, 8] != 2)
213                                 //    a[8, 8] = 3;
214                                 if (map[r, s] != 2)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
215                                     map[r, s] = 3;
216                                 //if (a[8, 6] != 2)
217                                 //    a[8, 6] = 3;
218                                 x++;
219                             }
220                             else if (map[x + 1, y] == 3)//解决人不能通过终点坐标问题
221                             {
222                                 map[x + 1, y] = 1;
223                                 map[x, y] = 0;
224                                 x++;
225                             }
226                             else if (map[x + 1, y] == 2 && map[x + 2, y] == 0)//人的下一步是箱子,箱子的下一步是空地
227                             {
228                                 map[x + 1, y] = 1;
229                                 map[x + 2, y] = 2;
230                                 map[x, y] = 0;
231 
232                                 //if (a[8, 8] != 2 && a[8, 8] != 1)
233                                 //    a[8, 8] = 3;
234                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子,而且人在终点上的,就让显示人,而不是终点
235                                     map[r, s] = 3;
236                                 //if (a[8, 6] != 2 && a[8, 6] != 1)
237                                 //    a[8, 6] = 3;
238 
239                                 x++;
240                             }
241                             else if (map[x + 1, y] == 2 && map[x + 2, y] == 3)//人的下一步是箱子,箱子的下一步是终点
242                             {
243                                 map[x + 1, y] = 1;
244                                 map[x + 2, y] = 2;
245                                 map[x, y] = 0;
246 
247                                 //if (a[8, 8] != 2)
248                                 //    a[8, 8] = 3;
249                                 if (map[r, s] != 2 && map[r, s] != 1)//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
250                                     map[r, s] = 3;
251                                 //if (a[8, 6] != 2)
252                                 //    a[8, 6] = 3;
253 
254                                 x++;
255                             }
256                             else //其中包括,人的下一步是墙,箱子的下一步是墙
257                                 Console.WriteLine("\a");
258                         }
259                         else
260                             Console.WriteLine("\a");
261                     }
262                     #endregion
263 
264                     MapDisplay(map);
265                 }
266 
267                 Console.Write("恭喜你过关!按回车键进入下一关:");
268                 ConsoleKeyInfo key1 = Console.ReadKey();
269                 if (key1.Key.ToString().ToLower() == "enter")
270                 {
271                     a += 1;
272                 }
273                 else
274                 {
275                     Console.WriteLine("你输入的有错!");
276                     break;
277                 }
278             }
279         }
280 
281         /// <summary>
282         /// 构造地图
283         /// </summary>
284         /// <param name="a">关数</param>
285         /// <returns>相应关数的地图</returns>
286         static int[,] Map(int a)
287         {
288             int[,] d = new int[10, 10];
289             if (a == 1)
290             {
291                 int[,] map1 = new int[10, 10]{
292                 {8,8,8,8,8,8,8,8,8,8},
293                 {8,0,0,0,8,0,0,0,0,8},
294                 {8,0,2,0,8,8,8,8,0,8},
295                 {8,0,0,0,0,0,0,8,0,8},
296                 {8,1,0,0,0,0,0,8,0,8},
297                 {8,0,0,0,8,0,0,0,0,8},
298                 {8,0,0,0,8,0,0,0,0,8},
299                 {8,0,3,0,8,0,0,0,0,8},
300                 {8,0,0,0,8,0,0,0,0,8},
301                 {8,8,8,8,8,8,8,8,8,8}};
302 
303                 return map1;
304             }
305             else if (a == 2)
306             {
307                 int[,] map1 = new int[10, 10]{
308                 {8,8,8,8,8,8,8,8,8,8},
309                 {8,0,0,0,8,0,0,0,0,8},
310                 {8,0,0,0,8,8,8,8,0,8},
311                 {8,0,0,0,0,0,0,8,0,8},
312                 {8,1,0,0,0,0,0,8,0,8},
313                 {8,0,0,0,8,0,0,0,0,8},
314                 {8,0,2,0,8,0,0,0,0,8},
315                 {8,0,0,0,8,0,0,0,0,8},
316                 {8,0,0,0,8,0,0,0,3,8},
317                 {8,8,8,8,8,8,8,8,8,8}};
318 
319                 return map1;
320             }
321             else if (a == 3)
322             {
323                 int[,] map1 = new int[10, 10]{
324                 {8,8,8,8,8,8,8,8,8,8},
325                 {8,0,0,0,8,0,0,0,0,8},
326                 {8,0,2,0,8,8,8,8,0,8},
327                 {8,0,0,0,0,0,0,8,0,8},
328                 {8,1,0,0,0,0,0,8,0,8},
329                 {8,0,0,0,8,0,0,0,0,8},
330                 {8,0,0,0,8,0,0,0,0,8},
331                 {8,0,0,0,8,3,0,0,0,8},
332                 {8,0,0,0,8,0,0,0,0,8},
333                 {8,8,8,8,8,8,8,8,8,8}};
334 
335                 return map1;
336             }
337             else
338             {
339                 int[,] map1 = new int[10, 10]{
340                 {8,8,8,8,8,8,8,8,8,8},
341                 {8,0,0,0,8,0,0,0,0,8},
342                 {8,0,2,0,8,8,8,8,0,8},
343                 {8,0,0,0,0,0,0,8,0,8},
344                 {8,0,0,0,0,0,0,8,0,8},
345                 {8,0,0,0,8,0,0,0,0,8},
346                 {8,0,1,0,8,0,0,3,0,8},
347                 {8,0,0,0,8,0,0,0,0,8},
348                 {8,0,0,0,8,0,0,0,0,8},
349                 {8,8,8,8,8,8,8,8,8,8}};
350 
351                 return map1;
352             }
353         }
354 
355         /// <summary>
356         /// 显示地图
357         /// </summary>
358         /// <param name="a">传入每一关的地图</param>
359         static void MapDisplay(int[,] a)
360         {
361             Console.Clear();
362             for (int i = 0; i < 10; i++)
363             {
364                 for (int j = 0; j < 10; j++)
365                 {
366                     //Console.ForegroundColor = ConsoleColor.White;
367 
368                     if (a[i, j] == 1)
369                         Console.Write("");
370                     else if (a[i, j] == 0)
371                         Console.Write("  ");
372                     else if (a[i, j] == 3)
373                     {
374                         //Console.ForegroundColor = ConsoleColor.Red;
375                         Console.Write("");
376                         //    Console.ForegroundColor = ConsoleColor.White;
377                     }
378                     else if (a[i, j] == 8)
379                         Console.Write("");
380                     else
381                         Console.Write("");
382                 }
383                 Console.WriteLine();
384             }
385         }//显示地图
386 
387         /// <summary>
388         /// 计算人和终点的坐标
389         /// </summary>
390         /// <param name="map">每一关的地图</param>
391         /// <param name="a">a=1 人的坐标,a=2是终点的坐标</param>
392         /// <param name="b">b=1 x的坐标,b=2 y的坐标</param>
393         /// <returns>坐标值</returns>
394         static int ZuoBiao(int[,] map, int a, int b)
395         {
396             int m = 0;
397             int[,] aa = map;
398             if (a == 1)
399             {
400                 if (b == 1)
401                 {
402                     for (int i = 0; i < 10; i++)
403                     {
404                         for (int j = 0; j < 10; j++)
405                         {
406                             if (aa[i, j] == 1)
407                                 m = i;
408                         }
409                     }
410                 }
411                 else
412                 {
413                     for (int i = 0; i < 10; i++)
414                     {
415                         for (int j = 0; j < 10; j++)
416                         {
417                             if (aa[i, j] == 1)
418                                 m = j;
419                         }
420                     }
421                 }
422             }
423             else
424             {
425                 if (b == 1)
426                 {
427                     for (int i = 0; i < 10; i++)
428                     {
429                         for (int j = 0; j < 10; j++)
430                         {
431                             if (aa[i, j] == 3)
432                                 m = i;
433                         }
434                     }
435                 }
436                 else
437                 {
438                     for (int i = 0; i < 10; i++)
439                     {
440                         for (int j = 0; j < 10; j++)
441                         {
442                             if (aa[i, j] == 3)
443                                 m = j;
444                         }
445                     }
446                 }
447             }
448 
449             return m;
450         }
View Code

eg.3

 4、函数递归

递归的几个特点

a、递归式,就是如何将原问题划分成子问题。

b、递归出口,递归终止的条件,即最小子问题的求解,可以允许多个出口。

c、界函数,问题规模变化的函数,它保证递归的规模向出口条件靠拢。

引入非递归 

从用户使用角度来说,递归真的很简便,对程序宏观上容易理解。递归程序的时间复杂度虽然可以根据T(n)=T(n-1)*f(n)递归求出,其中f(n)是递归式的执行时间复杂度,一般来说,时间复杂度和对应的非 递归差不多,但是递归的效率是相当低的它主要发费在反复的进栈出栈,各种中断等机制上(具体的可 以参考操作系统)更有甚者,在递归求解过程中,某些解会重复的求好几次,这是不能容忍的,这些也 是引入非递归机制的原因之一。

递归转非递归的两种方法 

1.一般根据是否需要回朔可以把递归分成简单递归和复杂递归,简单递归一般就是根据递归式来找出递推公式(这也就引申出分治思想和动态规划)。

2.而复杂递归一般就是模拟系统处理递归的机制,使用栈 或队列等数据结构保存回朔点来求解。

例题:

 1.求解阶乘

 阶乘的定义就是n!=n*(n-1)! 0!=1 1!=1 

根据定义我们很容易就想到递归方法,做法如下

int Fact(int n)

{ 
    if(n==0) return 1; //递归出口
    return n*Fact(n-1) //n*Fact(n-1)就是递归式,其中n-1就是界函数
} 

2.再看Fibonacci的例子

 定义:某项的值等于前两项的和,其中第一和第二项为1。

 根据定义我们很容易写出程序,这里就不写出来了,当我们用笔划几下的时候我们是否会发现有很多解是重复求出的。举个例子要求F(5) 

F(5)=F(4)+F(3); 

F(4)=F(3)+F(2); 

F(3)=F(2)+F(1); 

其中F(3)求解2次。这显然就是时间的浪费。下面我们用递推技术来转化成非递归从例子可以发现我们可以倒过来求解,即从底到顶把F(n)之前要计算的东西保存下来。

程序就是:

int Fibona(int n) 
{ 
    int p1=1,p2=1; 
    //int a[100]={0}; 
    //a[1]=1,a[2]=1; 
    for(int i=3;i<=n;i++)   //从三开始就可以了,后面的return包括1,2
两种情况
    { 
         int r=p1;  
        //递推,可以使用数组全部保存
         p1=p2; 
         p2+=r; 
        //a=a[i-1]+a[i-2] 
      } 
    return p2; 
    //return a[n]; 

}  

           

 

 

posted @ 2015-07-14 19:26  其实哥很宅  阅读(334)  评论(0编辑  收藏  举报