# 第二周【程式課程】第二章 陣列、迴圈與列舉筆記 ###### tags: `程式課程` 講者:錢鼠Coinmouse ## 隱含型別 ```cs var atk = 100; // 攻擊力整數100 var name = "Hero" ; // 名字"Hero" var posX = 1.0f; //x座標浮點數1.0 var posy = 1.0; //座標雙浮點數1.0 ``` * 編譯時根據賦予的初始值決定變數類型 * 不可在無賦值的情況下宣告 * 不容易辨明變數用途的情況下斟酌使用 ## 陣列 ### 一維陣列 ```csharp! int[] bulletDmgs = new int[] {30,29,42}// 總共三個子彈傷害(賦值) var first = bulletDmgs[0]; //第一發傷害(30) var second = bulletDmgs[1]; // 第二發傷害(29) var third - bulletDmgs[2]; // 第三發傷害(42) //預先宣告花色數量(不賦值) string[] pokerSuits = new string[4]; pokerSuits[0] = "Spade" ; //第一個花色"黑桃 //以下類推 ``` * 宣告時賦值會給予賦值數量的陣列長度(Length) * 陣列的第一個元素從0開始 * 指定取第幾個陣列元素(Element)的數字稱之為素引Index) * 低於0或大於陣列宣告長度的索引會報錯 ### 二維陣列 ```csharp! int[,] grids = new int[, ] ( (1, 2, 3), (4, 5, 6), [7, 8, 9, float[,] reds = new float[1024, 768] Console.WriteLine (grids[1, 1]); //顯示5 (剛好是正中間元素) Console.writeLine (grids ,GetLength (0)) ; //顯示3 (橫的數量) Console.WriteLine (grids.GetLength(1)) ; //顯示3 (縱的數量) Console.WriteLine (grids . Length) ; //顯示9 (全長3*3) ``` * 可以在宣告時給予指定元素 * 每個子陣列都必須等長 * 使用GetLength(0)、GetLength(1)分别取得[m,n]陣列中的mn ### 三維(較少用,略) ### 不規則陣列 ```csharp! int[][] grids = new int[] []f new int[](1, 2, 3], new int[](4, 5, 6], new int[](7, 8, 9, 10] Console.WriteLine (grids.Length) ; //子陣列有3個,顯示3 Console.WriteLine (grids[0].Length) ; //第一個子列有3個元素,顯示3 Console.WriteLine (grids [2].Length) ; //第三個子陣列有4個元素.顯示4 ``` * 等於是陣列的陣列,每個子陣列長度不一定相同 ## 迴圈 ```csharp! int sum = 0; for (int i = 1; i <= 10; i++) ( //從1~10·每執行一次1就加一 sum += i; Console.WriteLine (sum) ; //總共55 ``` * 格式為for(初始化;執行條件;執行後行為) ```csharp! int sum(int[,] nums){ int sum = 0; for (int i = O; i < nums.GetLength(0); i++){ for (int j= 0; j<nums.GetLength(1) ; j++){ sum t= nums[i, j]; } } return sum; } ``` * 多個圈的結構我們稱之為巢狀圈(NestedLoop) * 要努力避免這種情形發生 ```csharp! // infinite loop int sum = 0; int i = 1; for (;;) //for的括內都可以填空 { sum += i; ++; } ``` * 任何可能無法終止的圈都可以稱作無窮圈(InfiniteLoop) ```csharp! // return int Search(int[] nums, int n){ for (int i = 0; i < nums.Length; i++){ if(nums[i] == n) return i; } return -1 ; } //陣列[1,2,3,4,5]中尋找3的index //在行到=2的時候就會return ``` * return會直接回傳而跳出函式 ```csharp! // break int Search(int[] nums, int n){ for (int i = 0; i < nums.Length; i++){ int index = -1; if (nums[i] == n){ index = i; break; } } return index; } ``` * 只跳離當前迴圈 ```csharp! // continue int Search(int[] nums, int n){ int index = -1; for (int i = 0; i < nums.Length; i++){ if (nums[i] != n){ continue; } index = i; } return index; } ``` * 直接跳下一次迴圈 | 關鍵字 | 定義 | 備註 | | -------- | ------------------------------------------ |:----:| | return | 跳出並回傳函式結果 | | | break | 中止迴圈,繼續執行接下來的程式碼 | | | continue | 跳下一個迴圈,該次迴圈中之後的邏輯不會執行 | | ```csharp! //foreach int Sum(int[] nums){ int sum = 0; foreach(var n in nums){ sum += n; } return sum; } ``` * 不用特地宣告index或判斷條件的語法糖(Syntactic Sugar) * **不可在foreach內修改圈元素**,會造成錯誤 ```csharp! //while int i = 0; int sum = 0; int[] nums = new int[] ( 1, 2, 3, 4 ); while (i < nums. Length) { sum += nums[i]; i++; } ``` * 先判斷再執行 ```csharp! int i = 0; int sum = 0; int[] nums = new int[] ( 1, 2, 3, 4 ); do { sum += nums [i]; i++; } while (i < nums.Length); ``` * 先執行再判斷 ## 列舉 ### 基本用法 ```csharp! enum EBotstate{ Idle, //閒置 Warn, //警戒 Combat, //戰鬥 Flee //逃跑 } var state = EBotState. Idle; ``` * 可用相較於int更為直觀的方式表現狀態等參數 * 可用編譯器檢查語法 ### 帶入數值 ```csharp! enum EBotstate : int { //宣告列舉的數值類型(僅限整數系列的類型) Idle = 0, //可以不賦值,預設從0開始 Warn, //預設從上一個列舉數值+1 Combat, //依此類推... Flee } var state = EBotstate.Idle; ``` * 可用任意整數類型(byte,short,int, ., e.t.c.) ```csharp! enum EDebuff : byte { None = 0b00000000,// 十進位為0 Poison = 0b00000001, // 十進位為1 Paralysis = 0b00000010, // 十進位為2 Bleeding = 0b00000100, // 十進位為4 Cursed = 0b00001000 // 十進位為8 } EDebuff curDebuff = EDebuff.Poison | EDebuff.Paralysis; bool HasDebuff(EDebuff current, EDebuff debuff){ return (current & debuff) != 0; } ``` * 也可作為一個位元操作的行為 * 在此範例中,這些狀態的數值以二進制為表示 * 當我們角色中了異常狀態的時候,可能不會只有一個,這時我們可以用 `curDebuff` 的寫法作為代表狀態為 Poision 與 Plarlysis 同時存在時的狀況,在案例裡為用或( | ) 計算,最後結果為 0b00000011,加起來為3,並用 HadDebuff 來判斷是否有此 buff 狀態。 ## 函式(二) ### 不定長度參數、關鍵字params ```csharp void printAll(params int[] nums){ var str = nums[0]. Tostring() ; //將第一個元素先轉為字串 for (int i = 1; i < nums.Length; i++){ str += ", " t nums[i]; //之後的數字之前加逗號 } //從第二個元素開始 Console.WriteLine (str); } printAll(new int[](1, 2, 3)); //結果為"1,2,3” printAll(2, 4, 6, 8, 10); //結果為2,4,6,8,10” ``` * params關鍵字表示宣告不定長度參數,僅限於函式使用,並且要接陣列類型參數 * 可以帶入同樣類型的陣列或元素類型任意數量 * 必須作為函式中的**最後(右邊)一個參數** * printAll 可以把數值轉成字串,並以一個"數值,數值,"的方式呈現 ### 選擇性參數(Optional Parameter) ```csharp! int Sumseries(int origin, int step, int rise = 1){ int sum = O; for (int i = 0; i < step; i++){ sum += origin + i * rise; } return sum; } SumSeries(1, 3) ; //1+2+3,rise為1·每次數值增加1 SumSeries (1, 3, 2) ; //1+3+5,rise為2,每次數值增加2 ``` * 呼叫時可省略被宣告為選擇性參數,示會自動使用預設的數值 * 選擇性參數必須在其他參數之後 ## 備註:第零章小筆記 勞贖(程式) \<details> \<summary>我的答案</summary> csharp string GiveMeABananaOl return "Banana"; \</details> ![](https://i.imgur.com/xspF9Zr.png) 這樣寫會有將資訊隱藏起來的效果