--- tags: 課程111ERP02 --- # 民國111.11.07 C# ## 第一節 chap 3-14 // loop 迴圈三兄弟 ``` private void button1_Click(object sender, EventArgs e) { for (int i = 1; i <= 10; i++) // i is private in the for loop { MessageBox.Show(i.ToString()); } } ``` // for迴圈的執行次數, 在迴圈開始時, 就已經固定了 ``` private void button2_Click(object sender, EventArgs e) { int i = 1; while (i <= 10) { MessageBox.Show(i.ToString()); i++; } } ``` // do while 的迴圈本體至少會被執行1次, 即使條件為假 //do while 的條件是後測 所以至少會被執行1次 // for , while 使用率 99% , do while 的使用率 1%(適用至少執行一次的案例) // do while 的迴圈, 結束要加 ; ``` private void button3_Click(object sender, EventArgs e) { int i = 1; do { MessageBox.Show(i.ToString()); i++; } while (i<=10); } ``` //結論:迴圈次數的掌握是關鍵 1.迴圈變數的初始值設定 2.迴圈變數的遞增值 3.迴圈結束的條件(避免迴圈成為無窮迴圈) //無窮迴圈 ``` private void button15_Click(object sender, EventArgs e) { for ( ; ; ) ; } ``` ``` private void button16_Click(object sender, EventArgs e) { while (true ) ; } ``` ``` private void button15_Click(object sender, EventArgs e) { do { ; } while (true); } ``` //作業1: 使用迴圈3兄弟, 求1~100的總和=5050 //作業2: 使用迴圈3兄弟, 求1~100的奇數總和 //作業3: 使用迴圈3兄弟, 將1~100的數,顯示在richTextBox 每列顯示10個數, 數中間用逗點隔開, 如下: 1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20, //作業3的 參考解答 ``` private void button1_Click(object sender, EventArgs e) { richTextBox1.Text = ""; for (int i = 1; i <= 100; i++) { richTextBox1.Text += i + ","; if (i % 10 == 0) { richTextBox1.Text += "\n"; } } } ``` //作業4: 製作一個九九乘法表, 顯示在richTextBox (要使用2個迴圈, 一個外圈; 一個內圈) 輸出格式如下: (使用 for , while 迴圈) 1x1=1 1x2=2 1x3=3 1x4=4 1x5=5 1x6=6 1x7=7 1x8=8 1x9=9 2x1=2 2x2=4 2x3=6 2x4=8 2x5=10 2x6=12 2x7=14 2x8=16 2x9=18 //參考解答思考方向 ``` using System; namespace ConsoleApplication { class Program { static void Main(string[] args) { for (int i = 1 ; i <= 9; i++) { for (int j = 1; j <= 9; j++) { Console.Write( i + "*" + j + "=" + (i * j).ToString("00") + " " ); } Console.Write("\r\n"); } Console.ReadLine(); } } } // class Demo { static void Main() { int i = 1; while (i <= 9) { int j = 1; while (j <= 9) { System.Console.Write("{0} ", i * j); j++; } i++; System.Console.WriteLine(); } } } // i-- private void button2_Click(object sender, EventArgs e) { int i = 10; while ( i> 0) { MessageBox.Show(i.ToString()); i--; } } private void button4_Click(object sender, EventArgs e) { for (int i = 1; i <= 10; i=i+2) // i+=2 也可以 { MessageBox.Show(i.ToString()); // 1 3 5 7 9 } } private void button5_Click(object sender, EventArgs e) { for (int i = 10; i >= 1; i--) { MessageBox.Show(i.ToString()); } } // if else private void button1_Click(object sender, EventArgs e) { int i=5; if (i > 1) { MessageBox.Show(i.ToString()); //5 } MessageBox.Show(i.ToString()); } private void button2_Click(object sender, EventArgs e) { int i = -5; if (i > 0) { MessageBox.Show("i>0"); } else { MessageBox.Show("i<0"); } MessageBox.Show("The end"); } ``` //if { } else { } 使用大括號來確定勢力範圍,是良好的習慣, 可以避錯 //以下邏輯錯誤示範: 邏輯錯誤不會出現紅色毛毛蟲 //忘記寫大括號, 但是有縮排對齊 //考不及格還是會顯示"恭喜過關"-->邏輯錯誤 //懶惰會報應現前: ``` private void button3_Click(object sender, EventArgs e) { int i = 50; if (i >=60) MessageBox.Show("i>=60"); MessageBox.Show("恭喜過關"); } ``` //正解如下: ``` private void button3_Click(object sender, EventArgs e) { int i = 50; if (i >=60) { MessageBox.Show("i>=60"); MessageBox.Show("恭喜過關"); } }; ``` 作業1: 輸入3個數字, 求最大者 (用Windows form改寫3-4 頁例題) //參考解答 ``` private void button1_Click(object sender, EventArgs e) { int n1, n2, n3, max; n1 = Convert.ToInt32(textBox1.Text); n2 = Convert.ToInt32(textBox2.Text); n3 = Convert.ToInt32(textBox3.Text); if (n1 > n2) { if (n1 > n3) { max = n1; } else { max = n3; } } else { if (n2 > n3) { max = n2;} else { max = n3; } } MessageBox.Show("max="+max.ToString()); } ``` if 四姊妹 1. if 2. if else 3. if else if 3.1 if if else 4. switch case 注意!! 1. else 不會單獨存在 2. else 會往前面找, 離他最近的if 配對(else 倒追 if) 作業:3數求最大, 使用 3元運算子 //參考解答 //方法1 ``` private void button1_Click(object sender, EventArgs e) { int n1, n2, n3, max; n1 = Convert.ToInt32(textBox1.Text); n2 = Convert.ToInt32(textBox2.Text); n3 = Convert.ToInt32(textBox3.Text); max = (n1 > n2) ? n1 : n2; max = (max > n3) ? max : n3; MessageBox.Show(max+ " is big"); } ``` //方法2 //本例是 巢狀的三元運算式(三元運算式裡面, 還有三元運算式) ``` private void button5_Click(object sender, EventArgs e) { int n1, n2, n3, max; n1 = Convert.ToInt32(textBox1.Text); n2 = Convert.ToInt32(textBox2.Text); n3 = Convert.ToInt32(textBox3.Text); max = (n1 > n2) ? ((n1 > n3) ? n1 : n3) : ( (n2 > n3) ? n2 : n3); MessageBox.Show(max + " is big"); } ``` 自我練習作業: 用程式產生費氏數列, 輸出前面40數字到 richTextBox, 每列10個數字, 數字間用逗點隔開, 結果如下: 0,1,1,2,3,5,8,13,21,34, 55,89,144,233,377,610,987,1597,2584,4181, 6765,10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 提示: 費波那契數列由0和1開始,之後的費波那契系數就是由之前的兩數相加而得出。首幾個費波那契系數是: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233… //遞迴作法 ``` Console.WriteLine("遞迴作法"); for (int i = 0; i < n; i++) { Console.Write(foo(i).ToString() + ","); } Console.WriteLine(); static Int64 foo(Int64 i) { if (i == 0 || i == 1) return i; else return foo(i - 1) + foo(i - 2); } ``` //陣列作法 ``` private void button2_Click(object sender, EventArgs e) { long[] array = new Int64[] { 0, 1 }; long tmp = 0; for (int i = 0; i <40 ; i++) { if (i == 0 || i == 1) richTextBox1.Text += array[i].ToString() + ","; else { tmp = array[0] + array[1]; richTextBox1.Text += tmp.ToString() + ","; array[0] = array[1]; array[1] = tmp; } } richTextBox1.Text += "\n"; } ``` 作業:使用Windows Form改寫3-6 例題 ``` private void button1_Click(object sender, EventArgs e) { int n; n = Convert.ToInt32(textBox1.Text.Trim()); if (n == 1) { MessageBox.Show("答錯了"); } else if (n == 2) { MessageBox.Show("答錯了");} else if (n == 3) { MessageBox.Show("答錯了");} else { MessageBox.Show("答對了");} } ``` 作業: 製作一個選擇題, 選擇答案(4), 回應正確 //使用 Panel 元件 (1) 太陽由西邊出來 (2) 0> 1 (3) 1 != 1 (4) 尼羅河位在埃及 if else 配對原則 else 會往上找離他最近的if 配對 "else" is impossible to exist alone 注意!! 1.巢狀if else 或if else if 由於結構複雜, 邏輯分析不容易,很容易出錯(新手,老手都會錯) 可改用列switch case條列式語法(從根本解決) 2.使用簡單if (條列式) , 搭配 switch case 可以解決多數的條件分類 //switch 後面的變數型態 和 case 後面的值, 型態必須相同 //switch 後面的變數型態有3種 // 1.number (數值) ``` private void button1_Click(object sender, EventArgs e) { int n; n = Convert.ToInt32(textBox1.Text); switch (n) { case 1: MessageBox.Show("1"); break; case 2: MessageBox.Show("2"); break; case 3: MessageBox.Show("3"); break; default: //以上皆非 預設 MessageBox.Show("other"); break; } } ``` //通常case 的後面都要加break; 用來跳脫 switch 不加break; 流程會進入下一個case 的判斷, //口訣: switch case default break; ``` private void button1_Click(object sender, EventArgs e) { int n; n = Convert.ToInt32(textBox1.Text); switch (n) { case 1: case 3: case 5: case 7: case 9: MessageBox.Show("奇數"); break; case 2: case 4: case 6: case 8: case 10: MessageBox.Show("偶數"); break; default: MessageBox.Show("other"); break; } } ``` //2.string (字串) //Trim() 去除字串前後空白 //ToUpper() 英文字轉成大寫 (有些人工作上只認識數字0~9 , 英文A~Z ) //舉例:船公司中英文名稱對照表 ``` private void button3_Click(object sender, EventArgs e) { string s; s = textBox1.Text.Trim().ToUpper(); //示範接龍 textBox1.Text.Trim().ToUpper(); switch (s) { case "A": MessageBox.Show("A"); break; case "B": MessageBox.Show("B"); break; case "C": MessageBox.Show("C"); break; default: MessageBox.Show("other"); break; } } ``` //3.運算式 1.1 //輸入-9 當測試值 ``` private void button1_Click(object sender, EventArgs e) { int n; n = Convert.ToInt32(textBox1.Text); switch (n % 2) { case 0: MessageBox.Show("餘數是偶數"); break; case 1: MessageBox.Show("餘數是奇數"); break; case -1: MessageBox.Show("餘數是-奇數"); break; default: MessageBox.Show("it is impossible"); break; } } ``` //3.運算式1.2 使用Math.Abs() absolute 絕對值 ``` private void button2_Click(object sender, EventArgs e) { int n; n =Math.Abs( Convert.ToInt32(textBox1.Text)); switch (n % 2) { case 0: MessageBox.Show("餘數是偶數"); break; case 1: MessageBox.Show("餘數是奇數"); break; default: MessageBox.Show("it is impossible"); break; } } ``` //3.運算式2 //switch後面使用關係運算式的技巧(3元運算式) ``` private void button1_Click(object sender, EventArgs e) { int n,r; n = Convert.ToInt32( textBox1.Text); r = n % 2; switch ( n= (r==0)?0:1 ) { case 0: MessageBox.Show("餘數是偶數"); break; case 1: MessageBox.Show("餘數是奇數"); break; default: MessageBox.Show("it is impossible"); break; } } ``` // 在case 中運算 ``` private void button5_Click(object sender, EventArgs e) { int n; n = Convert.ToInt32(textBox1.Text); //n=12 switch (n % 2) { case 0: { MessageBox.Show("餘數是偶數"); if (n > 10) { for (int i = 1; i <= 5; i++) { MessageBox.Show(i.ToString()); } } break; } case 1: MessageBox.Show("餘數是奇數"); break; default: MessageBox.Show("it is impossible"); break; } } ``` 作業:使用Windows Form改寫3-9 例題 //C# switch case 不能判斷 (關係運算式) //作業1: 使用 if else 或 switch case 語法 電影按照輸入的年齡分級 普遍級, 保護級, 輔導級, 限制級 普遍級(簡稱「普」級):一般觀眾皆可觀賞。 保護級(簡稱「護」級):未滿6歲之兒童不得觀賞,6歲以上12歲未滿之兒童須父母、師長或成年親友陪伴輔導觀賞。// age >= 6 && age<12 輔導十二級(簡稱「輔十二」級):未滿12歲之兒童不得觀賞。 // age >= 12 && age<15 輔導十五級(簡稱「輔十五」級):未滿15歲之兒童不得觀賞。 // age >=15 && age<18 限制級(簡稱「限」級):未滿18歲之人不得觀賞。 // age >=18 //作業2:輸入所得金額, 計算所得稅 稅率 所得金額 \--------------------------------------------- 5% TWD 0~540,000 12% TWD 540,001~1,210,000 20% TWD 1,210,001~2,420,000 30% TWD 2,420,001~4,530,000 40% TWD 4,530,001以上 //以上2個作業, 會安排線上作業發表 //3-22頁, 迴圈的中斷(break) ``` private void button1_Click(object sender, EventArgs e) { for (int i=1; i <= 10; i++) { if (i == 5) { continue; //會跳到到開頭, 繼續做 // Application.Exit(); //強制結束程式 } if (i == 9) { break; //半途而廢 , 離開迴圈 } MessageBox.Show(i.ToString()); } MessageBox.Show("the end"); } ``` //若要強制結束程式的執行 使用 Application.Exit(); 使用在出現嚴重錯誤時 ``` private void button1_Click(object sender, EventArgs e) { MessageBox.Show("I will exit"); Application.Exit(); MessageBox.Show("the end"); // never show } ``` //老師示範如何由工作列強制終止程式 \------------------------------------------------------------------------- 心得: 以下會改變程式的執行順序 1.Application.Exit(); 強制結束程式的執行 2.return 回上一層程式 3.break 中斷迴圈的執行 4.continue 回到迴圈開始處 //2022.05.16 //作業:本例迴圈中斷(break , continue), 改用 while 迴圈語法 //作業:寫程式示範上述改變程式的執行順序( Application.Exit() , return ) //參考範例 ``` private void button1_Click(object sender, EventArgs e) { int i = 1; while( i <= 10) { if (i == 5) { i++; continue; //會跳到到開頭, 繼續做 } if (i == 9) { break; //半途而廢 } MessageBox.Show(i.ToString()); i++; } MessageBox.Show("the end"); } ``` //return 回到上一層 ``` private void button3_Click(object sender, EventArgs e) { MessageBox.Show("I will return"); return; MessageBox.Show("the end"); // never show } ``` /////Random Number 亂數 ``` private void button1_Click(object sender, EventArgs e) { int guess; Random r = new Random(); guess = r.Next(1, 50); // (1<= r < 50) 1,2,3,....,49 MessageBox.Show(guess.ToString()); } ``` //大樂透是一種樂透型遊戲。您必須從01~49中任選6個號碼 ``` private void button3_Click(object sender, EventArgs e) { int n1 = new int(); //int() is a Class(類別) // 宣告 n1 是一個整數變數, 這個n1變數是按照 int()這個類別建立的(佔據空間) int n2; n1 = 1; n2 = 2; MessageBox.Show((n1 + n2).ToString()); } ``` //會使用亂數是一種技能, 短時間就可以產生大量隨機資料(獲得超能力) //亂數可以亂槍打鳥, 雖不中亦不遠矣(樣本->母體) //程式語言多內建亂數功能 //如果車輪餅是物件變數(Object), 做車輪餅的"模子"就是類別(Class) //產生6個大樂透的號碼 ``` private void button2_Click(object sender, EventArgs e) { int guess; Random r = new Random(); label1.Text = ""; for (int i = 0; i <= 5; i++) { guess = r.Next(1, 50); label1.Text += guess.ToString() + ","; } } ``` //作業:本例6個大樂透的號碼, 輸出到richTextBox ====================================================================== /////// console 控制台, 看守台 // console= 螢幕 + 鍵盤 如何進入 主控台應用程式 (.NET Framework) ? 建立新專案的步驟: 1. C# > Windows > 主控台 2. 主控台應用程式 (.NET Framework) 或是在專案類型搜尋輸入 : 主控台 c# 用途:C#的主控台應用程式,省略圖型介面控制項,僅使用單純的C#語法 微軟許多線上的範例使用主控台模式 ``` namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Console.WriteLine("hello"); Console.WriteLine("你好"); Console.ReadLine(); //暫停 } } } //Console.ReadLine() 的使用方法 (read 1 line at a time) namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string s; s = Console.ReadLine(); Console.WriteLine("s=" + s); Console.ReadLine(); // pause } } } ``` //輸入字串轉成數字 ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int n; Console.WriteLine("Please input n=" ); n= int.Parse( Console.ReadLine() ); n++; Console.WriteLine("n++ ="+n); Console.ReadLine(); } } } ``` //使用參數(parameter, argument, 引數) ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.WriteLine("1+{0}={1}", 1, 2); Console.ReadLine(); //1+1=2 int n1 = 1, n2 = 2; Console.WriteLine("1+{0}={1}", n1, n2); Console.ReadLine(); //1+1=2 } } } ``` //換行 與顯示中文 範例1: ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.WriteLine("{0} \n {1} "," 春眠不覺曉","處處聞啼鳥"); Console.ReadLine(); } } } ``` 範例2: ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.WriteLine("{0} ~ {1} "," 春眠不覺曉","處處聞啼鳥"); //春眠不覺曉 ~ 處處聞啼鳥 Console.ReadLine(); } } } ``` 作業:使用控制台程式,列印下列輸出 春眠不覺曉 處處聞啼鳥 夜來風雨聲 花落知多少 //Console.ReadLine() vs Console.Read(); //輸入3個字串 ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string s; for (int i = 1; i <= 3; i++) { Console.WriteLine("Please input:"); s=Console.ReadLine(); Console.WriteLine("You input="+s); } Console.ReadLine(); } } } ``` //Console.Read()的秘密 (應用在物聯網的序列通訊) //C# 的 Console.Read() 會讀入整數 (read 1 character at a time and turn it into an integer) // Enter 換行鍵, 會產生 0D 0A 2字元 (ASCII) (Enter makes 0D 0A , 2 control characters at a time) //0D = 13 Carriage Return (CR) //0A = 10 Line Feed (LF) //使用 Console.Read() 按Enter, 會讀入3個整數 //範例1.1 使用Read() //注意!! 讀入1, 2, 3, 三個整數, 得到 49, 50, 51, 三個ASCII的值 ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int n, CR, LF; int s=0; for (int i = 1; i <= 3; i++) { Console.WriteLine("Please input:1 Enter , 2 Enter , 3 Enter"); n =Console.Read(); // 1, 2, 3 CR = Console.Read(); //0D LF = Console.Read(); //0A s += n; Console.WriteLine("You input="+n); } Console.WriteLine("sum="+s); //49+50+51 =150 (ASCII 的10進位編號) Console.ReadLine(); } } } ``` //練習: 本例輸入 A, B, C 的結果為何? (ANS:198) //範例1.2 使用ReadLine() ``` static void Main(string[ ] args) { string s ; int sum = 0; for (int i = 1; i <= 3; i++) { Console.WriteLine("Please input:1 Enter , 2 Enter , 3 Enter"); s = Console.ReadLine(); // 1, 2, 3 sum += int.Parse(s); Console.WriteLine("You input=" + s); } Console.WriteLine("sum=" + sum); //1+2+3 =6 Console.ReadLine(); } ``` //範例2 (使用轉型 (int) (char) ) //要求:使用Console.Read() 讀入1, 2, 3, 三個字元 , 希望相加後, 得到的答案是:6 怎麼做? ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { char c; int CR, LF; int s = 0; for (int i = 1; i <= 3; i++) { Console.WriteLine("Please input:1 Enter , 2 Enter , 3 Enter"); c = (char) Console.Read(); // 1, 2, 3 CR = Console.Read(); //0D LF = Console.Read(); //0A s += (int) c -48; //(int) 可以省略 Console.WriteLine("You input=" + c); } Console.WriteLine("sum=" + s); //1+2+3 =6 Console.ReadLine(); } } } ``` //範例3 //C語言的字元和數值可以混和運算 ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { char c='1'; //49 int s ; s = c + 1; //49+1 Console.WriteLine("sum=" + s); //50 Console.ReadLine(); } } } ``` 作業:使用 Console.Read() 輸入 1 ~10 累加 ,計算和=55 //參考解答 ``` namespace ConsoleApplication1 { class Program { static void Main(string[] args) { char c; int cr, lf, n; int s = 0; for (int i = 1; i <= 9; i++) { Console.WriteLine("Please input:1 ,2 ,3~9"); c = (char)Console.Read(); // 1, 2, 3 cr = Console.Read(); //0D lf = Console.Read(); //0A s += (int)c - 48; //(int) 可以省略 Console.WriteLine("You input=" + c); } Console.WriteLine("Please input:10"); n = int.Parse( Console.ReadLine()); // 10 s += n; Console.WriteLine("sum=" + s); //1+2+3+..+10 =55 Console.ReadLine(); } } } ``` ========================================================================== chap 3-1 // array 陣列是多個相同名稱的變數 ``` private void button1_Click(object sender, EventArgs e) { int[] a=new int[5]; //宣告a是一個整數陣列 ,有5個儲存空間 // int[] a; // a = new int[5]; int s; a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; a[4] = 5; // a[5] = 6; // cause runtime error System.IndexOutOfRangeException: '索引在陣列的界限之外。 s = a[0] + a[1] + a[2] + a[3] + a[4]; //15 MessageBox.Show(s.ToString()); } ``` //作業: 仿上例, 用陣列計算 1+2+3+...+10 //索引溢位(overflow)是陣列的夢魘(索引去撞牆) //索引(index), 註標(subscript) //如何記住陣列宣告方式? ---------------------------------------------------------------------- // int[] a -> a 是一個整數陣列[ ] // = new int[5] -> a是按照整數[5個儲存空間]的模子做出來的 //陣列的初始值用一對{大括號}括起來 // int[] a = new int[5] {1,2,3,4,5}; ``` private void button2_Click(object sender, EventArgs e) { int[] a = new int[5] {1,2,3,4,5} ; // int[] a = new int[ ] {1,2,3,4,5} ; //省略大小, 自己會算 int s=0; for (int i = 0; i <= 4; i++) { s += a[i]; } MessageBox.Show(s.ToString()); //15 } ``` //C語言的陣列由0開始起算 // n個儲存空間的編號由 0 到 n-1 //搭配的for迴圈也由0開始 // 學C#要放棄由1起算的日常習慣(要放棄由1起算的堅持) // 因為C#元件內部陣列,物件內部成員計算,是由0起算 ``` private void button3_Click(object sender, EventArgs e) { int[] a = new int[5] {1,2,3,4,5}; int s = 0; for (int i = 0; i <= 4; i++) { s += a[i]; // s=s+a[i]; } MessageBox.Show(s.ToString()); } ``` //作業1: 使用textbox1~7, 輸入一周7日溫度(浮點數), 求一周平均溫度 //使用 for , while 迴圈各做一次 //使用陣列來存一周7日溫度 //陣列(array) 和 迴圈(for loop) 是最佳拍檔 //以下是浮點數陣列 ``` private void button3_Click(object sender, EventArgs e) { double[] a = new double[5] { 1.1, 2.2, 3.3, 4.4, 5.5 }; double s = 0; for (int i = 0; i <= 4; i++) { s += a[i]; } MessageBox.Show(s.ToString()); //16.5 } ``` //作業2:計算夏季一周均溫 (高溫均溫,低溫均溫) , 使用陣列 //計算方式:每日高溫取天花板整數, 低溫取地板整數. 例如(29.3, 21.3) --> (30, 21) // 每日溫度格式: (溫度1, 溫度2) 數字大的是高溫, 數字小的是低溫, 要自行判斷高低溫 // 如果輸入有負數, 是輸入錯誤, 負數要轉成正數(因為夏天的低溫不會低於0度) // 一周溫度如下: (溫度1, 溫度2)={ (28.5, 20.1), (-21.3, 29.3), (30.2, 22.2), (21.7, 23.7), (32.6, -24.9), (23.4, 25.2), (34.1, -26.4) } // 最後求出來的一周高低均溫, 使用4捨5入法, 取到整數 //chap 4-5 ``` private void button4_Click(object sender, EventArgs e) { int[] a = new int[5] { 1, 2, 3, 4, 5 }; int len,len2, ub, lb,rnk; len = a.Length; //5 *最常使用的屬性 len2 = a.GetLength(0); //5 第0維的長度 ub = a.GetUpperBound(0); // 4 a[4] 第0維的上限 lb = a.GetLowerBound(0); // 0 a[0] 第0維的下限 rnk = a.Rank; // 1 1 dimension 維度 MessageBox.Show(len.ToString()); MessageBox.Show(len2.ToString()); MessageBox.Show(ub.ToString()); MessageBox.Show(lb.ToString()); MessageBox.Show(rnk.ToString()); } ``` ``` private void button5_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; Array.Sort(a); //ascending ASC *最常使用的方法 for (int i = 0; i <=4; i++) { MessageBox.Show(a[i].ToString()); } } ``` //作業 : 使用array.Length屬性, 配合 for 迴圈 1. 列印 int[] a = new int[5] { 1, 2, 3, 4, 5 }; 到 richTextBox 2. 列印 int[] a = new int[5] { 5, 4, 3, 2, 1 }; 到 richTextBox 參考: ``` private void button1_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; //Length=5 for (int i = 0; i < a.Length; i++) //使用array.Length屬性, 避免迴圈索引溢位(index out of range) { MessageBox.Show(a[i].ToString()); } } ``` //作業 : 一個陣列使用亂數,產生5個元素, 經過排序(Sort)後, 求最大值和最小值 可用GetUpperBound(0)取上限值 GetLowerBound(0)取下限值 //作業1:使用亂數, 產生6個大樂透的號碼, 放入陣列, 並輸出到label ``` private void button1_Click(object sender, EventArgs e) { int[] a = new int[6]; Random r = new Random(); for (int i = 0; i < a.Length; i++) //a.Length=6 { a[i] = r.Next(1, 50); } label1.Text = ""; for (int i = 0; i < a.Length; i++) { label1.Text += a[i].ToString()+", "; } } ``` //作業2:陣列a的內容 , 給陣列b ``` private void button6_Click(object sender, EventArgs e) { int[] a = new int[] { 1, 2, 3, 4, 5 }; int[] b = new int[5]; b = a; //陣列a的內容 , 給陣列b , 陣列名稱a, 是陣列的位址(address) int s = 0; for (int i = 0; i <= 4; i++) { s += b[i]; } MessageBox.Show(s.ToString()); //15 } ``` //作業2:產生6個大樂透的號碼, 並輸出到label, 去除重複號碼 //參考 ``` private void button1_Click(object sender, EventArgs e) { int[] a = new int[10]; Random r = new Random(); for (int i = 0; i < a.Length; i++) //a.Length=10 { a[i] = r.Next(1, 50); //產生10個樂透號碼 } Array.Sort(a); //排序 label1.Text = ""; for (int i = 0; i < a.Length; i++) //顯示前10個號碼(可能會有重複的值) { label1.Text += a[i].ToString() + ", "; } int[] result = a.Distinct().ToArray(); //Distinct() 唯一 , 注意: a的內容不變喔! //新產生的陣列 int[] result 不會有重複的值, a.Distinct() 會產生一個運算後的暫存數列 for (int i = 0; i < 6; i++) //取出前6個號碼 { label2.Text += result[i].ToString() + ", "; } } ``` // a.Length ``` private void button9_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; Array.Sort(a); //ascending ASC for (int i = 0; i < a.Length; i++) { MessageBox.Show(a[i].ToString()); } } ``` //作業 : 陣列中求最大值, 最小值 ``` private void button3_Click(object sender, EventArgs e) { int[] a = new int[] { 5, 4, 3, 2, 1, 100 }; Array.Sort(a); MessageBox.Show("MIN=" + a[0]); //1 MessageBox.Show("MAX=" + a[a.Length-1]); //100 } ``` \/\/Array.Sort Array.Reverse Array.Clear ``` private void button6_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; Array.Sort(a); //ascending ASC 12345 Array.Reverse(a); //DESC descending 54321 for (int i = 0; i < a.Length; i++) { MessageBox.Show(a[i].ToString()); //54321 } MessageBox.Show("Clear ary"); Array.Clear(a,0,a.Length); // Array.Clear (陣列名稱,起始位置,刪除個數) for (int i = 0; i < a.Length; i++) { MessageBox.Show(a[i].ToString()); } } ``` // Array.Clear(a:需要清除的陣列, index:起始索引, length:要清除的元素個數) //作業 : 字串陣列排序 ``` private void button4_Click(object sender, EventArgs e) { string[] a = new string[] { "this", "is", "a", "book" }; Array.Sort(a); for (int i = 0; i < a.Length; i++) { MessageBox.Show(a[i].ToString()); // a book is this } Array.Clear(a, 0, a.Length); //字串陣列清除成為虛值null if (a[0] == null) { MessageBox.Show("1.reset to null. YES"); } if (a[0] == "") { MessageBox.Show("1.reset to Empty. NO"); //本行不會執行 } ////////////////////////////////////////////////////////////// for (int i = 0; i < a.Length; i++) { a[i] = ""; } if (a[0] == null) { MessageBox.Show("2.reset to null. NO"); //本行不會執行 } if (a[0] == "") { MessageBox.Show("2.reset to Empty. YES"); } } ``` //c#在此碰到尷尬的問題, 解套如下: //作業 : 空字串是 null ? 或 "" ? ``` private void button6_Click(object sender, EventArgs e) { string s1,s2; s1 = ""; //空字串 s2 = null; if (s1 == "" ) { MessageBox.Show("s1 is \"\" "); } if (s2 == null) { MessageBox.Show(" s2 is null"); } if (String.IsNullOrEmpty(s1)) MessageBox.Show( "S1 is null or empty"); if (String.IsNullOrEmpty(s2)) MessageBox.Show("S2 is null or empty"); if (String.IsNullOrEmpty(textBox1.Text)) MessageBox.Show("textBox1.Text is null or empty"); } ``` //注意!! 1. C# 的 "" 不等於 null String.IsNullOrEmpty 是方便的方法,可讓您同時測試字串值是 Null 或 Empty 。 2.若要簡化: 使用 "" //陣列的搜尋 //Array.IndexOf() 搜尋某數的位置 **面試熱門考題 //.IndexOf搜尋是循序搜尋(1,2,3,...,n) ``` private void button11_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; int n = Array.IndexOf(a, 1); if (n >= 0) MessageBox.Show("n=" + n.ToString()); //4 else MessageBox.Show("找不到"); } ``` ``` private void button1_Click(object sender, EventArgs e) { string[] a = new string[5] { "A", "B", "C", "D", "E" }; int n = Array.IndexOf(a, "D"); if (n >= 0) MessageBox.Show("BINGO=" + n.ToString()); //3 else MessageBox.Show("找不到"); } ``` //Array.BinarySearch() 的速度比 IndexOf() 快 //陣列需要事先排序, 才可以使用Array.BinarySearch() //用於判斷某數存在陣列裡面嗎?( 要先做Array.Sort(a)排序) //適用較大陣列, 搶時間 //二分搜尋(BinarySearch)法,每次只要搜1/2的範圍就好,快 ``` private void button7_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; Array.Sort(a); //ascending ASC 1 2 3 4 5 int input, where; input = Convert.ToInt32(textBox1.Text); where = Array.BinarySearch(a, input); if (where >= 0) MessageBox.Show(where.ToString()); else MessageBox.Show("找不到"); } ``` //作業: 使用亂數產生一個介於1~100 之間的數字,使用者輸入一個數來猜它 //數字(Bingo)由亂數產生 //猜的過程顯示在richTextBox 55=bingo Guess 1: (1+100)/2=51 大 Guess 2: (51+100)/2=76 小 Guess 3: (51+76)/2=64 小 Guess 4: (51+64)/2=58 小 Guess 5: (51+58)/2=55 bingo 二分搜尋的虛擬碼大致如下: ``` void binarysearch(Type data[1..n], Type search) { Index low = 1; Index high = n; while (low <= high) { Index mid = (low + high) / 2; if (data[mid] = search) { print mid; return; } else if (data[mid] > search) { high = mid - 1; } else if (data[mid] < search) { low = mid + 1; } } print "Not found"; } ``` //Q:為什麼二分搜尋的速度比較快? Ans:每次搜尋的範圍只有1/2 // c# 四捨五入範例 ``` private void button9_Click(object sender, EventArgs e) { double d; d = Math.Round(3.14159, 2); MessageBox.Show(d.ToString()); //3.14 MessageBox.Show(Math.Round(3.14159, 3).ToString()); //3.142 } ``` // demo binary search(二分搜尋法) 1 2 3 4 5 || 6 7 8 9 10 //indexof 不用事先做排序 ``` private void button5_Click(object sender, EventArgs e) { int[] a = new int[] { 1, 2, 3, 6, 5, 4 }; int input, where; input = Convert.ToInt32(textBox1.Text); where = Array.IndexOf(a, input); MessageBox.Show(where.ToString()); } ``` //心得: 1.小陣列的搜尋使用 Array.IndexOf() 2.大陣列的搜尋使用 Array.BinarySearch(); 111.05.23 二維陣列(2 dimension array) = 矩陣(matrix) 二維陣列由橫向的列(row) 和縱向的行(column) 所組成 //注意!! 二維陣列的處理順序: 先列後行, 由上而下, 由左而右 ``` private void button6_Click(object sender, EventArgs e) { int[,] a = new int[3, 4] { { 11,12, 13,14 }, { 21,22, 23,24 }, { 31,32, 33,34 } }; for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { MessageBox.Show(a[i, j].ToString()); } } foreach (var p in a) { MessageBox.Show("for value=" + p); } int len, len0, len1; len = a.Length; MessageBox.Show("total len=" + len.ToString()); //12 len0 = a.GetLength(0); MessageBox.Show("len0=" + len0.ToString()); //3 row len1 = a.GetLength(1); MessageBox.Show("len1=" + len1.ToString()); //4 column } ``` //作業: 本例改用 a.GetLength(0) a.GetLength(1) 做雙層迴圈的判斷,有效防止索引溢出撞牆 // a.GetLength(0) 第1維 (列) // a.GetLength(1) 第2維 (行) ``` int[,] a = new int[3, 4] { { 11, 12, 13,14 },{ 21 ,22, 23,24 },{ 31, 32, 33, 34 } }; for (int i = 0; i < a.GetLength(0); i++) { for (int j = 0; j <a.GetLength(1); j++) { MessageBox.Show(a[i, j].ToString()); } } ``` //作業: 輸入一周三餐菜單(或飲料)[7,3] 到2維陣列 然後顯示菜單(可用richTextBox) //進階作業:查詢某個菜色 出現的位置 //例如查詢 [排骨飯] 在周三中午供應 練習1: ``` private void button1_Click(object sender, EventArgs e) { string[,] a = new string[3, 3] { {"飯糰" ,"包子", "饅頭" }, { "白米" ,"紫米", "五榖" }, { "青菜" ,"豆腐", "湯" } }; for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { richTextBox1.Text+=a[i, j].ToString()+"\t"; } richTextBox1.Text += "\n"; } } ``` 練習2: ``` string[,] a = new string[3, 3] { {"飯糰" ,"包子", "饅頭" },{ "白米" ,"紫米", "五榖" },{ "青菜" ,"豆腐", "湯" } }; private void button2_Click(object sender, EventArgs e) { for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { richTextBox1.Text += a[i, j].ToString() + "\t"; } richTextBox1.Text += "\n"; } } private void button3_Click(object sender, EventArgs e) { string input; input = textBox1.Text.Trim(); for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 2; j++) { MessageBox.Show("Traverse at:" + i.ToString() + ", " + j.ToString() +"="+ a[i, j]); if (a[i, j] == input) { MessageBox.Show("Bingo! "+input + " at " + i.ToString() + ", " + j.ToString()); break; } } } ``` //矩陣相乘1 //對應的元素相乘, 處理比較簡單 , 使用2個for 迴圈 //ERP班同學,儘量把相乘矩陣設計成大小相同, 避錯才是王道 練習3: 二個 3x3的矩陣, 對應的元素相乘, 結果輸出到 richTextBox ``` private void button1_Click(object sender, EventArgs e) { int[,] a = new int[3,3] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; int[,] b = new int[3,3] { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } }; richTextBox1.Text = ""; // 1 4 9 // 4 10 18 // 7 16 27 for (int i = 0; i <= 2; i++) { for (int j = 0; j <=2; j++) { richTextBox1.Text += (a[i, j] * b[i, j]).ToString() + "\t"; } richTextBox1.Text += "\n"; } } ``` //練習3的作業: 1.先個別輸出上例二個 3x3的矩陣,到 richTextBox 2.再把二個 3x3的矩陣對應的元素相乘, 結果輸出到 richTextBox //矩陣相乘2 //對應的元素相乘(列*行), 處理比較複雜 , 使用3個for 迴圈 練習4: A=2x3 B=3x2 A*B=2x2 A={ A(0,0), A(0,1), A(0,2), A(1,0), A(1,1), A(1,2)} B={ B(0,0), B(0,1), B(1,0), B(1,1), B(2,0), B(2,1)} A*B= A{0,0}*B{0,0}+A{0,1}*B{1,0}+A{0,2}*B{2,0}, A{0,0}*B{0,1}+A{0,1}*B{1,1}+A{0,2}*B{2,1} A{1,0}*B{0,0}+A{1,1}*B{1,0}+A{1,2}*B{2,0}, A{1,0}*B{0,1}+A{1,1}*B{1,1}+A{1,2}*B{2,1} 矩陣A 乘 矩陣B, 結果輸出到 richTextBox (要使用3層for 迴圈) //進階練習題目,可省略 //口訣: 一個在列把風, 一個在行把風, 一個動手相乘 ``` private void button1_Click(object sender, EventArgs e) { int[,] a = new int[2,3] { { 1, 2, 3 }, { 4, 5, 6 } }; int[,] b = new int[3,2] { { 1, 2 }, { 1, 2 }, { 1, 2 } }; richTextBox1.Text = ""; // 6 12 // 15 30 int s = 0; for (int i = 0; i <= 1; i++) { for (int j = 0; j <=1; j++) { for (int k = 0; k <= 2; k++) { s += a[i, k] * b[k, j]; } richTextBox1.Text += s.ToString() + "\t"; s = 0; } richTextBox1.Text += "\n"; } } ``` //foreach 是 for 迴圈的進階版語法(配合物件導向處理), 依序拜訪(traverse)陣列中的每一個元素 //foreach 是 for 迴圈的表弟 //polling(輪詢, 網路領域用語, 也是[依序拜訪]的意思 ) //foreach one in array ``` private void button7_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; foreach (int p in a) //pointer { MessageBox.Show(p.ToString()); } int[,] b = new int[3, 4] { {10,20,30,40} , {5,15,25,35}, {12,24,36,48} }; foreach (int p in b) { MessageBox.Show(p.ToString()); } } ``` //foreach (int p in a) = foreach (var p in a) = foreach (object p in a) //練習:把上例結果, 輸出到 richTextBox //foreach 懶惰用法 object p , 可以指向任何型態的陣列 // p 是object 型態 ``` private void button9_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; foreach (object p in a) //pointer { MessageBox.Show(p.ToString()); } int[,] b = new int[3, 4] { {10,20,30,40} , {5,15,25,35}, {12,24,36,48} }; foreach (object p in b) { MessageBox.Show(p.ToString()); } } ``` //object 變數型態的用法(可存任意資料型別) //object 處理的速度較慢 ``` private void button6_Click(object sender, EventArgs e) { object j1, j2, j3; j1 = 1; j2 = "abc"; j3='A'; MessageBox.Show(j1.ToString()); MessageBox.Show(j2.ToString()); MessageBox.Show(j3.ToString()); } ``` //object 陣列 //龍生九子, 子子不同 (object array) //C語言當初設下的嚴格資料型態, 在物件導向中被解放了,(物極必反) ``` private void button4_Click(object sender, EventArgs e) { object[] a = new object[5] { 5, "字串", 3.14 , 'A', true }; foreach (object p in a) //pointer { MessageBox.Show(p.ToString()); } } ``` // foreach index ``` private void button5_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; int i=0; foreach (var p in a) //pointer { MessageBox.Show("a[i]="+i.ToString()+" is "+p.ToString()); i++; } } ``` //心得: foreach 需要處理陣列索引(index)的時候, 改用 for 迴圈 比較直接 // foreach index (進階) 使用LINQ寫法 ``` private void button5_Click(object sender, EventArgs e) { int[] arr = new int[5] { 1, 2, 3, 4, 5 }; foreach (var p in arr.Select((value, ind) => new { ind, value })) { var index = p.ind; var value = p.value; MessageBox.Show("index=" + index.ToString() + " value= " + p.value.ToString()); } } ``` // foreach 也支援 break continue ``` private void button1_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; foreach (int p in a) //pointer { if (p == 3) continue; MessageBox.Show(p.ToString()); } MessageBox.Show("2nd loop"); foreach (int p in a) { if (p == 3) break; MessageBox.Show(p.ToString()); } } ``` ////作業: 使用foreach 顯示一周三餐菜單[7,3] 2維陣列 , 結果輸出到richTextBox //補充1: 委派 delegate 4-9 //魔法棒 可以點石成金 ``` private void button10_Click(object sender, EventArgs e) { int[] a = new int[5] { 1, 2, 3, 4, 5 }; Action<int> myaction = new Action<int>(doSquare ); //本行可省略 Array.ForEach(a, doSquare); } void doSquare(int p) { MessageBox.Show((p * p).ToString()); } void plus1(int p) { MessageBox.Show((p +1).ToString()); } ``` //補充2: //列舉器的使用方法(chap7) //可以讓C#處理資料結構的問題 ``` using System.Collections; private void button1_Click(object sender, EventArgs e) { int[] a = new int[5] { 5, 4, 3, 2, 1 }; foreach (object p in a) //pointer { MessageBox.Show(p.ToString()); } MessageBox.Show("使用列舉器取出陣列元素"); // Interface Enumerator IEnumerator myenum = a.GetEnumerator(); while (myenum.MoveNext()) { MessageBox.Show( myenum.Current.ToString() ); } MessageBox.Show("Reset 列舉器 read again"); myenum.Reset(); while (myenum.MoveNext()) { MessageBox.Show(myenum.Current.ToString()); } Stack mstack = new Stack(); foreach (int p in a) { mstack.Push(p); } MessageBox.Show("mstack has :" +mstack.Count.ToString()+ " POP from stack"); while (mstack.Count > 0) { MessageBox.Show(mstack.Pop().ToString()); } } ``` //enum列舉資料型別 //enumerate --> en number 數字化 -->用變數名稱(文字)來代表(取代)數字 //用"文字"來取代"數字" // en number a difficult number to an easy name. //人類擅長記憶名稱, 記不住複雜數字, 例如:家人的身分證號碼 / 手機號碼/生日, 記不住 //範例:請你使用Unicode 來朗誦"床前明月光 疑似地上霜" 並評估情境感覺如何 //\u5e8a\u524d\u660e\u6708\u5149\u7591\u4f3c\u5730\u4e0a\u971c //常數的集合(限整數型態使用) 2-43 // enum enumerate 數字化 //可以簡化複雜整數的處理 //人類腦力的記憶有限,不善於記憶長串複雜的數字,可用文字代表 ``` enum Weekdays : int { Monday=1, Tuesday=2, Wendesday=3, Thursday=4, Friday=5, Saturday=6, Sunday=7 }; private void button1_Click(object sender, EventArgs e) { int d; d = (int) Weekdays.Sunday; MessageBox.Show( d.ToString()); //7 } enum tel : int { husband = 0910123456, wife = 0920123456, son = 0930123456 }; private void button2_Click(object sender, EventArgs e) { int t; t = (int) tel.son; MessageBox.Show(t.ToString("0000000000")); // with leading zero MessageBox.Show(t.ToString()); // without leading zero 前置零會變成空白 } ``` 2022.5.38 //struct結構 structure 2-45頁 //各種資料型態型變數的集合(結構是混和資料型態, 由使用者依需要自行定義) //struct裡若變數需要公用,要宣告為public ``` struct Student { public int sno; //整數 public string sname; //字串 int age; //private private int tel; } private void button1_Click(object sender, EventArgs e) { Student john; john.sno = 1001; john.sname = "JOHN"; Student mary; mary.sno = 1002; mary.sname = "MARY"; MessageBox.Show(john.sno.ToString() + john.sname); MessageBox.Show(mary.sno.ToString()+mary.sname); //MessageBox.Show("Age="+john.age); } ``` //補充: class和struct,所有的變數預設都是屬於private. 而在struct裡若變數需要公用 要宣告為public class和struct兩者主要就是將一些變數或函數集結在一起,成為一種新的型態; class比struct多了一個建構和解構的觀念,也就是一個變數在宣告成class型態的時候, 當這個變數被產生﹙變數生命週期的開始﹚時,系統會去呼叫這個class的建構函數, 讓程式撰寫者可以進行一些初始化的動作﹙包含類似要求記憶體,設定初始值之類的﹚; 而當變數將被釋放﹙變數生命週期的結束﹚時,系統會去呼叫這個class的解構函數, 讓程式撰寫者可以進行一些收尾的動作﹙通常是處理記憶體釋放之類的﹚ 就以我個人的習慣而言,通常如果是簡單的資料組,我會宣告成struct型態﹙感覺就是純粹資料的集結﹚例如: ``` struct Student{ char Name[20]; int Score; } ``` 這就是純粹將姓名和分數集結成一個結構體。 如果是結構的資料必須進行某些特別處理或計算的,通常習慣寫成類別,例如: ``` class Dog{ int ID; public: char Name[20]; void Run(); ... } ``` 在這個狗的類別當中,就包含了簡單的結構內變數,以及專屬這個類別的函數﹙例如跑、跳、呼吸什麼的﹚ // use int() class 類別 // 物件來自類別 類別是藍圖 ``` private void button1_Click(object sender, EventArgs e) { int a; a = 1; MessageBox.Show(a.ToString()); int b = new int(); b = 2; MessageBox.Show(b.ToString()); } ```