第二阶段_第四家小节_C#基础2
?
?
第三小節
?
?
方法重載
?
//方法重載:方法名稱相同,參數列表不同
//適用性:在不同條件下,解決同一類問題
//優點:讓調用者解決一類問題,記憶1個方法。
?
要求:返回值相同
練習分鐘小時的重載
?
ref——引用參數
引用參數,為地址,相當于指針。
?
?
?
out——輸出參數
輸出參數類似引用參數,但輸出參數在函數中必須修改,調用方法前可以不賦值。
?
?
?
一維數組
?
?
數組讀取
?
?
練習
?
?
?
?
?
?
?
?
?
?
?
錄入成績練習
?
?
?
?
?
獲取最大值練習
?
?
數組寫法與練習
?
計算今年第幾天
?
?
?
?
?
?
練習自學Array的方法
Forreach
:只能讀
:全部
?
依次讀取全部元素。
?
?
?
數組簡元素進行比較
?
?
冒泡排序
缺點:通常交換次數過多。
?
?
選擇排序(性能提升)
?
?
?
Params
意義:簡化調用者的調用難度。
?
?
形式用法:
?
調用:
?
?
?
?
?
?
?
?
?
?
?
?
?
二維數組
形式:
?
?
?
從下到上,從右到左
?
?
?
?
?
?
?
聲明
?
從左到右,從上到下
?
從右到左,從下到上
?
用法:
?
arr.length//表示行數*列數;
arr.Getength(0);// 行數
arr.Getlength(1);// 列數
?
?
相關語法
?
Array 數組基類(父類)
object 萬類之祖
var 隱式(推斷)類型
?
Array的API
?
?
?
?
交錯數組
?
?
特點:參差不齊的數組
?
長短不一的數組,交錯數組的每個元素都是一維數組。
[1][ ][2]
[ ][ ][ ][3][ ]
[ ][ ][4][ ]
創建具有3個元素的交錯數組(3行)
int[][] array;
array = new int[3][];--->前邊方括號填包括幾個一維數組,后邊方括號里不能加東西
賦值:
array[0] = new int[3];
array[1] = new int[5];
array[2] = new int[4];
長度可相同。
//將數據1賦值給交錯數組的第一個元素的第1個元素
array[0][0] = 1;
array[0][2] = 2;
array[1][2] = 3;
array[2][1] = 4;
讀取array:(遍歷交錯數組)
foreach(var item in array)
{
foreach(var element in item)
{
Console.WriteLine(element);
}
}
//交錯數組.Length 交錯數組元素總數(行數)
//交錯數組[索引].Length 交錯數組元素的元素總數(某一行的列數)
for(int r=0;r<array.Length;r++)//交錯數組的元素數
{
for(int c =0;c<array[r].Length;c++)//交錯數組第一個元素的元素數
{
Console.WriteLine(array[r][c]);
}
}
?
?
?
?
形式:
float[][] arr3 = new float[3][];
//創建一維數組賦值給交錯數組的第一個元素
arr3[0] = new float[2];
arr3[1] = new float[4];
arr3[2] = new float[3];
//將數據1賦值給交錯數組的第一個元素的第二個元素
arr3[0][1] = 1;
arr3[1][0] = 2;
arr3[2][2] = 3;
獲取所有元素
Foreach
foreach (float[] item in arr3)//遍歷交錯數組的元素(一維數組)
{
foreach (var element in item)//遍歷交錯數組元素的元素
{
Console.WriteLine(element);
}
}
For
for (int r = 0; r < arr3.Length; r++)
{
for (int c = 0; c < arr3[r].Length; c++)
{
Console.Write(arr3[r][c] +"\t");
}
Console.WriteLine();
}
}
?
?
arr3.Length 交錯數組的元素數
arr3[0].Length 交錯數組第一個元素的元素數
?
?
復習
?
?
?
?
?
參數數組
使用params關鍵字定義的
只能用于形參列表
?
?
?
?
1.原始
參數數組
正常數組整數相加
整數相加需求//參數個數不確定,類型確定
形式:
static int Add(int[] arr)
?
調用:
Int sum =add(new int[]{1,2,3,4,5});
?
參數數組整數相加
形式:
整數相加需求//參數個數不確定,類型確定
static int Add(params int[] arr)
?
調用:
Int sum =add(1,2,3,4,5);
?
?
對于調用者來說更方便,對于方法內部而言,就是普通一維數組
整數相加的方法:(個數不確定,類型能確定)
用到params的數組要放在形參最后面, Add(int a,params int[] arr)
private static int Add(params int[] arr)【params 可以使調用者直接傳遞一組數據類型相同的變量集合,也可以不傳】
{
int sum;
for(int i =0;i<arr.Length;i++)
{
sum+=arr[i];
}
}
foreach也可,因為foreach只對自身只讀,這里是sum 變化,foreach不變化
Main()
{
//int a=Add(new int[]{1,2,3,4,5});
int a = Add(1,2,3,4,5);---->用了params 就不用再new int[]
int b = Add();--->用了params也可以不傳
}
?
復習
?
?
?
?
?
彩票練習
?
?
答案
?
private static void Main2()
{
int[] myTicket = BuyTicket();
?
Console.WriteLine("我買的彩票:");
PrintTicket(myTicket);
Console.WriteLine("驗證我的中獎潛力……");
?
int count = 0;
int level;
do
{
count++;
int[] ticket = CreateTicket();
//購買彩票與開獎彩票對比
level = TicketEquals(myTicket, ticket);
?
Console.WriteLine("*********開獎號碼:*********");
PrintTicket(ticket);
?
if (level != 0)
Console.WriteLine("恭喜,{0}等獎。累計花費:{1}元", level, count * 2);
} while (level != 1);
}
?
private static int[] BuyTicket()
{
int[] ticket = new int[7];
?
for (int i = 0; i < ticket.Length - 1; )
{
Console.WriteLine("請輸入第{0}個紅球號碼:", i + 1);
int redNumber = int.Parse(Console.ReadLine());
?
if (redNumber < 1 || redNumber > 33)
Console.WriteLine("您輸入的數字超過紅球號碼范圍:1--33");
//[重點:判斷輸入的號碼在數組中是否存在]
else if (Array.IndexOf(ticket, redNumber) >= 0)
Console.WriteLine("當前數字已經存在,請重新錄入");
else
ticket[i++] = redNumber;
}
?
int blueNumber;
do
{
Console.WriteLine("請輸入籃球號碼:");
blueNumber = int.Parse(Console.ReadLine());
if (blueNumber >= 1 && blueNumber <= 16)
ticket[6] = blueNumber;
else
Console.WriteLine("請輸入數字超過籃球號碼:1--16");
} while (blueNumber < 1 || blueNumber > 16);//數字不在1--16之間 再次執行
?
return ticket;
}
?
private static Random ran = new Random();
private static int[] CreateTicket()
{
int[] ticket = new int[7];
//[重點:生成多個不重復的隨機數]
for (int i = 0; i < 6; )
{
//思路:生成隨機數,判斷是否存在,不在則存儲
int num = ran.Next(1, 34);
if (Array.IndexOf(ticket, num) == -1)
ticket[i++] = num;
}
ticket[6] = ran.Next(1, 17);
//紅球號碼排序[重點:指定范圍的排序]
Array.Sort(ticket, 0, 6);
return ticket;
}
?
private static int TicketEquals(int[] myTicket1, int[] ranTicket2)
{
//判斷紅球號碼中獎數量
//思路:我的第1個號碼在隨機彩票的紅球號碼段中是否存在
// 我的第2個號碼在隨機彩票的紅球號碼段中是否存在
//[重點:在指定范圍內檢查是否具有相同元素]
int redCount = 0;
?
for (int i = 0; i < 6; i++)
{
if (Array.IndexOf(ranTicket2, myTicket1[i], 0, 6) != -1)
redCount++;
}
?
int blueCount = myTicket1[6] == ranTicket2[6] ? 1 : 0;
?
int level;
if (redCount + blueCount == 7)
level = 1;
else if (redCount == 6)
level = 2;
else if (redCount + blueCount == 6)
level = 3;
else if (redCount + blueCount == 5)
level = 4;
else if (redCount + blueCount == 4)
level = 5;
else if (blueCount == 1)
level = 6;
else
level = 0;
return level;
}
?
private static void PrintTicket(int[] ticket)
{
for (int i = 0; i < ticket.Length; i++)
{
Console.Write(ticket[i] + "\t");
}
Console.WriteLine();
}
?
?
輸出#號練習
?
?
?
?
?
?
?
冒泡排序:發現【更】小的則交換
?
?
?
?
圖片
?
代碼
//缺點:通常交換次數過多。
private static int[] OrderBy1(int[] array)
{
//1.取數據
for (int r = 0; r < array.Length - 1; r++)
{
//2.比較
for (int c = r + 1; c < array.Length; c++)
{
//3.發現更小則交換
if (array[r] > array[c])
{
int temp = array[r];
array[r] = array[c];
array[c] = temp;
}
}
}
return array;
}
?
選擇排序:發現【最】小的則交換
圖片
?
代碼
?
private static int[] OrderBy(int[] array)
{
//1.取數據
for (int r = 0; r < array.Length - 1; r++)//輪
{
//2.查找最小索引
int minIndex = r;//假設下當前元素就是最小索引
for (int c = minIndex +1; c < array.Length; c++)//次
{
//發現更小的元素
if (array[minIndex] > array[c])
{
//記錄位置(替換假設的最小索引)
minIndex = c;
}
}
//3.交換
if (minIndex != r)
{
int temp = array[minIndex];
array[minIndex] = array[r];
array[r] = temp;
}
}
return array;
}
?
?
2048核心算法
?
//*******************2048核心算法*****************************************
/*需求分析1.0
1.向上移動
--- 獲取列數據,形成一維數組
* --- 去除零元素(將非零元素向前移動)
* ---合并數據
* -- 如果相鄰元素相同
* -- 將后一個元素累加到前一個元素上
* -- 將后一個元素清零
* --- 去除合并過程中產生的零元素(將非零元素向前移動)
* --- 還原列數據
*
2.向下移動
--- 獲取列數據,形成一維數組
* --- 去除零元素(將非零元素向后移動)
* ---合并數據
* -- 如果相鄰元素相同
* -- 將前一個元素累加到后一個元素上
* -- 將前一個元素清零
* --- 去除合并過程中產生的零元素(將非零元素向后移動)
* --- 還原列數據
?
*
需求分析2.0
1.向上移動
--- 獲取列數據(從上到下),形成一維數組
--- 調用合并數據方法
* --- 還原列數據(從上到下)
*
2.向下移動
--- 獲取列數據(從下到上),形成一維數組
--- 調用合并數據方法
* --- 還原列數據(從下到上)
*
3.合并數據
* --- 調用去除零元素
* ---合并數據
* -- 如果相鄰元素相同
* -- 將后一個元素累加到前一個元素上
* -- 將后一個元素清零
* --- 調用去除零元素
?
4.去零方法(將非零元素向前移動)
*/
?
答案
?
移動零
private static void RemoveZero(int[] array)
{
//創建新數組0 0 0 0
int[] newArray = new int[array.Length];
int newIndex = 0;//新數組索引
//將參數中非零元素,依次存入新數組2 2 2 0
for (int i = 0; i < array.Length; i++)
{
if (array[i] != 0)
{
newArray[newIndex++] = array[i];// 存入 自增
}
}
//返回新數組
//return newArray;
//array = newArray;//修改棧中引用
newArray.CopyTo(array, 0); //拷貝元素 array[0] = newArray[0];
}
?
合并相同項
private static void Merge(int[] array)
{
RemoveZero(array);//2 0 2 2 --> 2 2 2 0
//合并數據
for (int i = 0; i < array.Length-1; i++)
{
//非零 且 相鄰相同
if (array[i] !=0 && array[i] == array[i + 1])
{
array[i] += array[i + 1];
array[i + 1] = 0;
}
}
RemoveZero(array);
//return array;
}
向上移動
?
private static void MoveUp(int[,] map)
{
int[] mergeArray = new int[map.GetLength(0)];
for (int c = 0; c < map.GetLength(1); c++)
{
//00 10 20 30
for (int r = 0; r < map.GetLength(0); r++)//從上到下 獲取列數據
mergeArray[r] = map[r, c];
?
Merge(mergeArray);
?
for (int r = 0; r < map.GetLength(0); r++)//從上到下 還原列數據
map[r, c] = mergeArray[r];
}
//return map;
}
向下移動
private static void MoveDown(int[,] map)
{
int[] mergeArray = new int[map.GetLength(0)];
for (int c = 0; c < map.GetLength(1); c++)
{
//30 20 10 00
for (int r = map.GetLength(0) - 1; r >= 0; r--)
mergeArray[3 - r] = map[r, c];//正向存入一維數組
?
Merge(mergeArray);
?
for (int r = map.GetLength(0) - 1; r >= 0; r--)
map[r, c] = mergeArray[3 - r];
}
//return map;
}
輸出顯示
private static void PrintMap(int[,] map)
{
for (int r = 0; r < map.GetLength(0); r++)
{
for (int c = 0; c < map.GetLength(1); c++)
{
Console.Write(map[r, c] + "\t");
}
Console.WriteLine();
}
}
?
//移動 Move(1 , map)
//導醫
移動
private static void Move(int direction,int[,] map)
{
switch (direction)
{
case 0:
MoveUp(map);
break;
case 1:
MoveDown(map);
break;
}
}
?
//目的:讓2048算法使用者,可以只記憶一個Move方法。
移動重寫
private static void Move(MoveDirection direction, int[,] map)
{
switch (direction)
{
case MoveDirection.Up:
MoveUp(map);
break;
case MoveDirection.Down:
MoveDown(map);
break;
}
}
主函數
static void Main()
{
int[,] map = new int[4, 4]
{
{ 2,4,0,4 },
{ 0,2,2,4 },
{ 2,0,0,2 },
{ 4,2,2,0 }
};
PrintMap(map);
Console.WriteLine("向上移動");
//MoveUp(map);//用戶需要記憶的方法過多
//Move(0, map);//用戶輸入的方向不明確
Move(MoveDirection.Up, map);//限定了取值范圍
?
PrintMap(map);
?
Console.WriteLine("向下移動");
//MoveDown(map);
Move(MoveDirection.Down, map);
PrintMap(map);
?
}
?
?
?
?
?
?
?
?
數據類型
?
類型圖示
?
?
?
?
值類型和引用類型圖示
?
?
?
?
?
?
?
?
?
?
Int[] arr;//在棧中聲明。A為位地址
arr= new int[]{1}
?
?
?
?
?
?
?
?
?
?
沒有【】就是改棧(重新開辟空間,附地址),有就是改堆。
String a="1"
String b=a
B="5"
得
S2="1"
?
?
?
?
面試:Stringbuilder與string的區別于優越性差異
?
?
?
?
?
?
應用1:賦值
?
圖示
?
?
?
代碼
static void Main3()
{
//方法執行在棧中
//方法內部聲明的變量,都在棧中分配空間。
int a;//在棧中
a = 1;//數據1在棧中( 因為值類型直接存數據 )
int b = a;//a將存儲的數據賦值b
a = 2;//修改棧中存儲的數據
Console.WriteLine(b);//?
?
//arr:數組的引用
int[] arr;//在棧中
arr = new int[] { 1 };//數組對象在堆中(引用類型數據在堆中)
int[] arr2 = arr;//arr將存儲的引用賦值給arr2
//arr[0] = 2;//修改堆中存儲的數據(數組對象)
arr = new int[] { 2 };//修改棧中存儲的引用
Console.WriteLine(arr2[0]);//?
?
string s1 = "老王";
string s2 = s1;//s1將存儲的引用賦值給s2
s1 = "老宋";//修改棧中存儲的引用,重新開辟空間存儲"老宋",替換棧中引用
Console.WriteLine(s2);//?
?
object o1 = 100;
object o2 = o1;//將o1存儲的引用賦值給o2
o1 = 200;//修改棧中存儲的引用,重新開辟空間存儲200,替換棧中引用
Console.WriteLine(o2);//?
}
?
應用2:比較
?
?
圖示
?
?
?
?
?
代碼
static void Main4()
{
//值類型存數據,比較數據
int a = 1, b = 1;
bool r1 = a == b;//比較數據1
Console.WriteLine(r1);//true
?
//引用類型存引用,比較引用
int[] arr01 = { 1 }, arr02 = { 1 };
bool r2 = arr01 == arr02;//比較數組引用
bool r3 = arr01[0] == arr02[0];//比較數組元素
Console.WriteLine(r2);//?
}
?
應用3:傳參
?
圖示
?
?
?
?
代碼
static void Main5()
{
int a1 = 1;
int[] arr1 = { 1 };
Fun1(a1, arr1);//a1將存儲的數據1、arr1將存儲的引用 傳入方法
Console.WriteLine(a1);//?1
Console.WriteLine(arr1[0]);//?2
?
int a2 = 1;
Fun2(ref a2);//將a2自身地址傳入方法
Console.WriteLine(a2);//2
?
//區別2:輸出參數進入方法前可以不賦值
int a3;//意圖:接收方法的結果
Fun3(out a3);//將a2自身地址傳入方法
Console.WriteLine(a3);//2
}
?
?
方法參數:值參數、引用參數、輸出參數
根據傳遞方式進行的劃分。
值參數:按值傳遞 --- 傳遞實參變量所存儲的內容
作用:傳遞信息
?
局部變量:在棧中,全局變量,不在
方法內種局部變量,為
private static void Fun1(int a,int[] arr)
{
//結論:引用類型,方法內部修改堆中數據,影響實參。
a = 2;
arr[0] = 2;//堆中數據
//arr = new int[] { 2 };//修改棧中引用
}
?
引用參數:按引用傳遞 --- 傳遞實參變量自身引用(內存地址)
//作用:改變數據
private static void Fun2(ref int a)
{//方法內部修改形參,等同于修改實參
a = 2;
}
?
輸出參數:按引用傳遞 --- 傳遞實參變量自身引用(內存地址)
//作用:返回結果
private static void Fun3(out int a)
{//區別1:方法內部必須修改輸出參數
a = 2;
}
?
static void Main6()
{
int num01 = 1, num02 = 2;
SwopNumber(ref num01, ref num02);
?
int area,per;
CalculateRect(10, 20, out area, out per);
?
?
string input = Console.ReadLine();
//int atk = int.Parse(input);
?
//嘗試著轉換,如果成功通過輸出參數返回結果。
// 如果失敗,可以通過返回值獲取結果。(木有異常)
int result;
if (!int.TryParse(input, out result))
{
Console.WriteLine("失敗嘍");
}
}
?
?
應用練習
交換兩個整數
矩形面積
?
?
?
裝箱yu拆箱
?
?
?
?
?
面試:發生拆裝箱的數目
例子:
ILspy
?
沒有拆裝箱,int number…….
?
Concat字符串拼接,本質是由concat,裝箱。。。。。。結局方案。.Tostring
Int->object形參為object
?
如果形參object,實參值類型,產生裝箱操作。
?
?
解決方案
1.
2.泛型:可以將數據類型作為參數傳入。
Private static void Fun2<Type>(To){
}
調用:Fun2<int>(To);
?
//如果形參object類型,實參值類型。會產生裝箱操作。
//解決方案:1.重載 2.泛型:可以將數據類型作為參數傳入方法。
?
?
String
?
?
特性1:字符串池(字符串常量)
// 節省內層
?
string s1 = "老王";
string s2 = "老王";
//s1 / s2 是同一對象
?
string s3 = new string(new char[] { '老', '宋' });
string s4 = new string(new char[] { '老', '宋' });
//s3 / s4 不是同一對象
?
?
?
?
特性2:不可變性
// 如果可變,就會破壞其他對象的內存空間
string s5 = "張飛";
s5 = "夏軍軍";//重新開辟空間 存儲新字符串,替換棧中引用。
//s5[0] = '夏';
char c1 = s5[0];
Console.WriteLine(s5);//? "張飛" -改變-> "夏軍"
?
string s6 = "老";
string s7 = s6 + "王";//"老王" 與 s1/s2 不是同一對象 "字符串變量參與的拼接,沒有使用字符串池的特性"
?
string s8 = string.Empty;//""
for (int i = 0; i < 10; i++)
{
//每次拼接都會產生一個新對象,產生1個垃圾
s8 = s8 + i.ToString();
//"" + "0"
//"0" +"1"
//"01" +"2"
}
Console.WriteLine(s8);//?
?
?
?
可變字符串
?
?
?
?
String和stringbuilder的優缺點
?
?
?
重點與練習
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的第二阶段_第四家小节_C#基础2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第二阶段_第三小节_C#基础
- 下一篇: 第二阶段_第五小节_C#基础3