2013年2月4日 星期一

小山的 C# 教學-第13課-NumericUpDown

本課簡介

此次課程主要是在複習 for 迴圈的用法
以及介紹 numericUpDown 這個元件

教學影片

注意:影片有高畫質 720P 的選項,可以看得更清楚喔!



重點提示

1. 如果程式碼中會使用到某些元件,最好給它取個名字
(教學中給 numericUpDown 元件取名為 rowChooser)

2. numericUpDown 是一種可以用來選擇數字的元件

3. numericUpDown 的 Value 屬性儲存的值是屬於 decimal 型別的

4. 想要將不同型別的值存入變數中必須經過轉換

5. 下面這種在值前面加上括號的轉換方式稱為強制轉型
int a; decimal b = 10; a = (int)b; 
6. for 迴圈可以巢狀使用,也就是一層 for 迴圈中還有另一層

補充

decimal 型別

這個型別在其他程式語言中比較少見。基本上,decimal 也是數字型別的一種。因此將它強制轉型成 int 型別或是 double 型別的變數都不會與預料的結果差別太多。這種型別的變數通常會拿來做金融或是財務上的計算,C# 有提供許多相關的支援。詳情可以看「相關資訊連結」。

強制轉型 

所謂強制轉型,簡單來說就是要求程式無論結果如何,都要想辦法把資料轉成另一種型別。當然如此強硬的轉換,往往得到的結果不如預期。因此一般來說,不同型別的變數是不能互相存取的。但是,如果你確定兩個型別都是類似性質的東西。你就可以使用強制轉型來進行轉換。像是數字之間的轉換就通常不會有問題。

強制轉型在 C 語言中,時常拿來處理記憶體分配以及 pointer 參數傳遞的問題。在 C# 中則拿來處理數字轉換比較多。

for 迴圈常用寫法

for (int i = 0; i < num; i++) for (int i = 1; i <= num; i++)
上面這兩種寫法在使用 for 迴圈時都很常見,而這兩者都會剛好將迴圈內的程式碼做 num 次。這次影片中使用的是後者的寫法。因為內層的迴圈需要用 i 來判斷現在進行到「第幾回合」,所以後者為佳。前者則比較常用於「陣列(Array)」的處理。因為陣列總是從「第 0 個」開始算,所以如果要跑過陣列裡的元素,最好是讓 i = 0 開始比較好。

練習

1. 如果仍不太了解程式運作的方式的話,請使用 Debug 工具,找個地方設中斷點,好好追蹤一下程式流程。

2. 教學中畫出的是由「*」構成的三角形,請試著劃出菱形

Ex: 選擇印出 5 列(中間的星號有5顆)

印出:

  *
 ***
*****
 ***
  *

相關資訊連結

MSDN 的 decimal 型別詳細資訊

http://msdn.microsoft.com/zh-tw/library/364x0z75%28v=vs.80%29.aspx

29 則留言:

  1. 你好 小山老師 我有看你的影片 交的很仔細 我是入門新手
    關於字幕的問題 我比較喜歡 因為 對於 有些老師的上傳的影片 我老實說 看不懂 跟聽不到
    有字幕的教學 可以讓我 不清楚 地方 可以更加了解

    回覆刪除
    回覆
    1. 感謝你的回饋,我會考慮是否要將字幕放回去

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 老師,可以放上印出菱形的程式嗎?

      刪除
    2. 因為我覺得從影片中就可以看到程式碼
      所以應該不太需要另外放

      刪除
  3. 作者已經移除這則留言。

    回覆刪除
  4. 是不是要用到if...else?
    只有輸入奇數值才能正常印出菱形算正常嗎....

    回覆刪除
  5. 感謝小山老師 精心設計的教學 讓新手的我可以很快速由基本進入
    看到這集有提到之後會拿掉字幕 覺得有點可惜
    因為有時是關靜音看教學的 如果沒有字幕 就會聽不到 呵呵
    當然還是看小山老師的方便性

    回覆刪除
  6. 我第一次學習C#是2008年大一的時後,已經過了10年了,如今想要自學,感謝你的影片讓我快速的學習!

    回覆刪除
  7. 感謝Yushan Lin的教學,淺顯易懂,作業已完成菱形部分.

    回覆刪除
  8. 小山老师能不能把你每个教学片子的习题答案公布下了?谢谢

    回覆刪除
  9. 練習題答案參考
    ------------------------------
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace WindowsFormsApptest
    {
    public partial class Form1 : Form
    {
    int i, j, k;
    public Form1()
    {
    InitializeComponent();
    }

    private void NumericUpDown1_ValueChanged(object sender, EventArgs e)
    {

    }

    private void Label1_Click(object sender, EventArgs e)
    {

    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void Button1_Click(object sender, EventArgs e)
    {
    string s = "";
    int row = (int)numericUpDown1.Value;
    for (i = 0; i < (row+1)/2; i++)
    {
    for (j = (row + 1) / 2; j > i+1; j--)
    {
    s += " ";
    }
    for (j = 0; j < 2*(i + 1)-1; j++)
    {
    s += "*";
    }
    s += "\n";
    }
    for (i = (row - 1) / 2; i > 0; i--)
    {
    for (j = (row - 1)/2; j > i-1 ; j--)
    {
    s += " ";
    }
    for (j= 0;j<2*i-1 ; j++)
    {
    s += "*";
    }
    s += "\n";
    }

    MessageBox.Show(s);
    }
    }
    }

    回覆刪除
    回覆
    1. 想請問老師
      我run出來的菱形有點歪歪的
      不知道是哪邊有問題

      刪除
  10. 這題有夠難,我花了一整個下午都想不到,一直到睡覺才解出來
    不過我的答案長得不太一樣,不是一三五三一的排列,而是一到五都顯示出來

    private void button1_Click_1(object sender, EventArgs e)
    {
    int row = (int)numericUpDown1.Value;

    string stars = "";

    for (int a = 1; a <= row; a++)
    {
    for (int c = a; c <= row; c++)
    {
    stars += " ";
    }
    for (int b = a; b >= 1; b--)
    {
    stars += "* ";
    }
    stars += "\r\n";
    }
    for (int a = 1; a <= row; a++)
    {
    for (int b = a; b >= 1; b--)
    {
    stars += " ";
    }
    for (int c = a; c <= row-1; c++)
    {
    stars += " *";
    }
    stars += "\r\n";
    }

    MessageBox.Show(stars);

    }

    回覆刪除
  11. 我的解答是不管輸入任何單數都會變成菱形,程式撰寫邏輯是把菱形分成上下兩部寫,所以會有兩個主要的for迴圈處理不同一個順、一個逆三角形,舉例來說,假設共有五行,正三角形為一二三行,倒三角形為四五行。每個主for迴圈裡面再拆分兩個for圈,一個處理空格" "(我用"-"代替),一個處理"*"
    private void button1_Click(object sender, EventArgs e)
    {

    int row = (int)rowChooser.Value;
    string result = "";
    //上半部主for(1、2、3行)
    for (int i=1;i<=(row+1)/2;i++)
    { //space
    for (int k = 1; k <= ((row + 1) / 2) - i; k++)
    {
    result += "-";

    }
    //star
    for (int q = 1; q <= 2*i-1; q++)
    {
    result += "*";
    }

    result +="\r";
    }
    //下半部主for(4、5行,但當作新的一個區塊,新的1、2行)
    //space
    for(int i = 1; i <= (row-1)/ 2; i++)
    {
    for (int k = 1; k <= i; k++)
    {
    result += "-";
    }
    //star
    for (int q = 1; q <= row-2*i; q++)
    {
    result += "*";
    }
    result += "\r";
    }


    MessageBox.Show(result);
    }
    }
    }

    回覆刪除
  12. 我資質愚鈍,花了1天才想出來,一開始是用很蠢的方式,後來才想到一個比較好的,兩個都貼上來分享一下,方式跟其他人寫得差不多,把菱形拆成上半跟下半,但要注意上半是到中間那行,下半是中間那行以下,不知道有沒有更好的寫法,希望神手們可以放上來借我參考一下,感謝萬分!

    * *
    *** ***
    ***** → ***** →
    *** ***
    * *
    程式結構大概是這樣→
    上半部
    for{
    for{空格數量
    for{*數量
    換行
    }
    下半部
    for{
    for{空格數量
    for{*數量
    換行
    }
    總共用了6個迴圈

    愚蠢版→
    private void button2_Click(object sender, EventArgs e)
    {
    int n = (int)numeric.Value;
    string m ="";
    for (int a = 1; a <= (n + 1)/2; a ++)
    {
    for(int b = (n+1)/2-a; b > 0; b-- )
    {
    m += " ";
    }
    m += "*";
    for(int c = 1; c <= a-1 ; c++)
    {
    m += "**";
    }
    m += "\n";
    }
    for (int i = (n / 2 + 1)+1; i <= n; i++)
    {
    for(int j = 1; j <= i - (n / 2 + 1); j++ )
    {
    m += " ";
    }
    m += "*";
    for (int k = n-i; k > 0; k--)
    {
    m += "**";
    }
    m += "\n";
    }
    MessageBox.Show(m);
    }

    改良版→
    private void button4_Click(object sender, EventArgs e)
    {
    int row = (int)numeric.Value;
    string result = "";
    for (int i = 1; i <= (row + 1) / 2; i++)
    {
    for (int j = (row + 1) / 2 - i; j > 0; j--)
    {
    result += " ";
    }
    for (int j = 1; j <= i * 2 - 1; j++)
    {
    result += "*";
    }
    result += "\r\n";
    }
    for ( int i = (row - 1) / 2; i > 0; i--)
    {
    for (int j = 0; j <= (row - 1) / 2-i; j++)
    {
    result += " ";
    }
    for (int j = i * 2 - 1; j > 0; j--)
    {
    result += "*";
    }
    result += "\r\n";
    }
    MessageBox.Show(result);

    }




    回覆刪除
    回覆
    1. 我發現用WinForm顯示出來會歪歪的,用主控台應用程式跑會顯示得比較正確喔!

      刪除
    2. 抱歉那個*號結構示意圖歪掉了 不要看

      刪除
  13. private void button1_Click(object sender, EventArgs e)
    {
    int row = (int)rowchooler.Value;
    string result = "";
    for (int i = 1;i <=row; i += 2)
    {
    for ( int k = row -1 ;k >= i; k-= 2 )
    {
    result += " ";
    }
    for (int j = 1;j <= i; j++)
    {
    result += "*";
    }
    result += "\r\n";
    }
    for (int i = row -2; i> 0;i -= 2)
    {
    for (int k = row -1; k >= i; k-= 2)
    {
    result += " ";
    }
    for (int j=1;j<=i;j++)
    {
    result += "*";
    }
    result += "\r\n";
    }
    MessageBox.Show(result);

    我用半形空格畫出來菱形會歪一邊,改用全形符號畫出來比較正~研究了好久終於成功了~!!

    回覆刪除
  14. private void button1_Click(object sender, EventArgs e)
    {
    int row = (int)rowchooser.Value;
    string result = "";

    for (int i = 1; i <=row; i+=2)
    {
    for (int k = row; k > i; k-=2)
    {
    result += " ";
    }
    for (int j = 1; j <= i; j++)
    {
    result += "*";
    }
    result += "\r\n";

    }

    for (int i =1 ; i <= (row-1)/2; i++)
    {
    for (int k = 1; k<=i; k++)
    {
    result += " ";
    }
    for (int j= 1; j<=row-(i*2); j++)
    {
    result += "*";
    }
    result += "\r\n";
    }

    MessageBox.Show(result);
    }

    回覆刪除
  15. 這題真的想好久,不過解除來還滿有成就感的
    不過菱形都有點歪歪的是正常嗎?
    private void button1_Click(object sender, EventArgs e)
    {
    string s = "";
    int row = (int)rowchooser.Value;
    for(int i=0;i<(row+1)/2;i++)
    {
    for(int j=0;j< row / 2 - i;j++)
    {
    s += " ";
    }
    for (int k = 0; k< i*2+1; k++)
    {
    s += "*";
    }
    s+="\r\n";

    }
    for(int i=0;ik+i*2;k++)
    {
    s+="*";
    }
    s += "\n\r";
    }
    MessageBox.Show(s);

    回覆刪除
  16. int row = (int)rowchooser.Value;
    string result = "";

    for(int i=1;i<=row;i++)
    {
    for(int k=1;k<=row-i;k++)
    {
    result += " ";
    }
    for(int j=1;j<=2*i-1;j++)
    {
    result += "*";
    }
    result += "\r\n";
    }

    for(int i=row-1;i>=1;i--)
    {
    for(int k=row-i;k>=1;k--)
    {
    result += " ";
    }
    for(int j=2*i-1;j>=1;j--)
    {
    result += "*";
    }
    result += "\r\n";
    }
    MessageBox.Show(result);

    回覆刪除
  17. 感謝小山分享教學 受益良多 菱形雖然有點歪 還是跟大家分享一下~
    int num = (int)numericUpDown1.Value;
    string a = "";
    for (int i = 1; i <=num; i=i+2) {
    for (int k =num;k>=i+1;k-=2)
    {
    a += " ";
    }
    for (int j = 1; j<=i ; j++) {
    a += "*";
    }
    a += "\r\n";
    }

    for (int i = num-2; i >=0; i = i-2)
    {
    for (int k = num; k >= i + 1; k -= 2)
    {
    a += " ";
    }
    for (int j = 1; j <=i; j++)
    {
    a += "*";
    }
    a += "\r\n";
    }
    MessageBox.Show(a);
    }

    回覆刪除
  18. 練習題使用if, else. 不知道這樣解法是否有隱藏問題?

    private void Push_Click(object sender, EventArgs e)
    {
    int row = (int)RowChoose.Value; //強制轉型將value值從decimal轉乘int
    string result = "";

    for (int i = 1; i <= row; i++)
    {
    if (2*i <= row+1)
    {
    for (int k = 1; 2*k <= row - 2*i + 1; k++)
    {
    result += " ";
    }

    for (int j = 1; j < 2 * i; j++)
    {
    result += "*";
    }

    for (int k = 1; 2*k <= row - 2 * i + 1; k++)
    {
    result += " ";
    }

    }
    else
    {
    for (int k = 1; 2 * k <= -row + 2 * i - 1; k++)
    {
    result += " ";
    }

    for (int j = 1; j <= 2 * (row-i) +1 ; j++)
    {
    result += "*";
    }

    for (int k = 1; 2 * k <= -row + 2 * i - 1; k++)
    {
    result += " ";
    }

    }

    result += "\r\n";
    }


    MessageBox.Show(result);
    }

    回覆刪除
  19. 作者已經移除這則留言。

    回覆刪除
  20. 作者已經移除這則留言。

    回覆刪除
  21. private void button1_Click(object sender, EventArgs e)
    {
    int row = (int)rowChooser.Value;
    string result = "";


    //菱形

    for (int l = 1; l <= row/2+1; l++)
    {

    for (int m = 1; m <= row - l; m++)
    {
    result += " ";
    }


    for (int k = 1; k <= 2 * l - 1; k++)
    {
    result += "*";
    }
    result += "\r\n";
    }

    for (int i = row /2; i >= 1; i--)
    {

    for (int j = 1; j <= row - i; j++)
    {
    result += " ";
    }


    for (int k = 1; k <= 2 * i - 1; k++)
    {
    result += "*";
    }

    result += "\r\n";
    }







    MessageBox.Show(result);
    }

    回覆刪除