# 第二周【程式課程】第二章 陣列、迴圈與列舉筆記
###### 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>

這樣寫會有將資訊隱藏起來的效果