計算機概論 Visual BASIC 程式設計 德霖技術學院 廖文淵 E-Mail: andres@dlit.edu.tw
第 7 課 迴圈與陣列
學習重點提示 陣列與迴圈的介紹 For...Next 迴圈 陣列與迴圈的基本概念 陣列的宣告與使用 峰迴圈轉話迴圈 陣列的進階使用
學習重點提示 其他常用迴圈 控制項陣列 While...Wend 迴圈 認識 Do While...Loop 迴圈 Do...Loop Until 迴圈 控制項陣列
陣列的基本觀念 陣列:一群變數的集合,這些變數都具有相同的名稱與相同的資料型態 使用陣列與不使用陣列的比較 變數要宣告 45 個 Dim eng1 As Integer ................... Dim eng45 As Integer eng1 = InputBox(請輸入英文成績) .................................. eng45 = InputBox(請輸入英文成績) 變數要宣告 45 個 輸入的程式碼要使用 45 個 Dim eng(45) As Integer For I = 1 To 45 eng(I) = InputBox("請輸入英文成績") Next I 利用迴圈重複執行 45 次輸入成績的程式碼 宣告一個名叫 eng 的陣列,裡面包含了 45 個整數
陣列的基本觀念 陣列的基本觀念:以「Dim eng(45) as Integer」來說 先不要看「(45)」就變成「Dim eng as Integer」,我們宣告了一個名叫的 eng 的整數變數。 加上「(45)」,就是「重複產生 45 個」的意思,也就是具有相同名稱的 eng 整數變數有 45 個。 陣列是一群具有相同名稱變數的集合,要能夠存取這些變數,我們需要透過「索引」的方式。 索引就是在「()」裡面加上數值。 比方說:eng(1) 就是存取編號(注意是編號不是順序)為 1 號的 eng 變數 eng(5) 當然就是存取編號為 5 號的 eng 變數。
陣列的基本觀念 Dim eng1 as Integer Dim eng(45) as Integer eng1 單一的變數 佔用連續的位置,括弧內就是索引值 eng(2) eng2 eng(3) eng(4) Dim eng3 as Integer ……….. eng3 eng(45)
迴圈的基本觀念 從 1 數到 10,從 1 數到 100 ,數所有的偶數或是奇數。程式語言中的數數稍微再複雜一點,在數每一個數時,有一段路要走,跟我們生活最相近的事情就是跑步。 今天上體育課,老師要我們跑操場 10 圈,要從出發的地點,跑完一圈回到起點才算是一圈。程式語言中的迴圈也是一樣,從程式碼中的迴圈起始行開始,到中途的折返點,再跳回到迴圈起始行才算是一圈。
迴圈的基本觀念 For I = 1 To 45:迴圈的起始行 eng(I) = InputBox("請輸入英文成績") Next I For I = 1 To 45:迴圈的起始行 變數 I 就是數數的基礎變數 I = 1 To 45:讓迴圈從 1 數到 45,也就是依序增加變數 I 的值,從 1 加到 45 Next I:就是中途的折返點,迴圈走到這裡就必須折返。迴圈的折返是用跳的,直接跳到迴圈的起始行。 從 1 數到 45,所以「eng(I) = InputBox(“請輸入英文成績”)」總共被執行了次 45。
陣列的宣告與使用 Dim 陣列名稱(大小) [ As 資料型態] 陣列名稱:就是變數名稱,命名規則跟變數是一樣的。 大小:就是指定陣列的大小。 比方說:Dim Arr(30) As Integer,就是宣告一個有 31 個元素的整數陣列Arr Visual BASIC 陣列的預設起始值是 0。 起始值可以經由指令 Option Base 來修改。Option Base 1 可以將陣列的下限設成 1。 As 資料型態:指定陣列的資料型態,如果不指定時,Visual BASIC 預設的資料型態是 Variant。
陣列的宣告與使用 Dim 陣列名稱(大小) [ As 資料型態] 陣列大小的宣告,也可以是指定範圍的 比方說:Dim Arr(-5 To 5) As Integer,就是宣告 Arr 為一整數陣列,他的索引值從 -5 到 5,所以 Arr 陣列中共有 11 個元素 (element)。
陣列的宣告與使用 範例 三年 A 班有 50 人,利用陣列來儲存輸入的英文成績 Dim eng(50), engval As Integer For I = 1 To 50 ‘迴圈執行 50 次 L10: engval = Val(InputBox("請輸入英文成績")) If engval < 0 Or engval > 100 Then GoTo L10 eng(I) = engval ‘依序儲存輸入的成績 Next I
陣列的使用須知 陣列在使用上,必須注意下面的幾件事情: 陣列的大小務必滿足實際的需求,在存取陣列的資料時,絕對不能超過陣列的大小。 比方說:Dim Arr(10) As Integer,存取 Arr(11) 或是 Arr(-5) 的內容,程式會出現執行上的錯誤:陣列索引超出範圍。 在指定陣列的資料型態時,務必視需要給陣列適當的資料型態。盡量不要宣告成 Variant。 因為 Variant 需要最多的記憶空間,一個具有 Variant 資料型態的陣列更是需要大量記憶體的大怪獸。
峰迴圈轉話迴圈 以程式的基本任務來說,我們最常執行的操作就是: 資料的尋找 資料的加總與排序都有類似的動作。 設定好尋找的範圍 執行「尋找」的任務 這個任務會在所有的資料中「重複」的執行 「一直到」所要的資料被找到或是資料已經看完為止 資料的加總與排序都有類似的動作。 這些陳述會一直執行到目標完成或是資料都看完才停止,這就是迴圈的基本精神。
峰迴圈轉話迴圈 選定資料範圍 執行特定的陳述(尋找資料) 目標達成了嗎?(找到資料了嗎) 資料看完了嗎? 設定下一個被尋找的對象 True False False 資料看完了嗎? 設定下一個被尋找的對象 True 執行其它的任務
峰迴圈轉話迴圈 構成一個迴圈的三件要素 設定資料的對象 要執行的工作 停止迴圈執行的條件
For...Next 迴圈 For 變數 = 起始值 To 終止值 [Step 間隔大小] 陳述區段1 [Exit For] 陳述區段2 預設間隔大小為正數。 如果間隔大小為負數, 「變數值 > 終止值」的判斷就會變成「變數值 < 終止值」。
For...Next 迴圈 For...Next 迴圈的構成要件以及運作情形如下: 一個控制迴圈的變數,任何變數的名稱都可以,只要是數值型態變數或是 Variant 都行。 迴圈控制變數的起始值與終止值,這裡個值可以是常數,數值變數或是算數運算式。 For I = 1 To 50 常數的起始值與終止值 For I = 1.25 To Y 常數的起始值與變數終止值 For I = X+Y To 30.5 運算式的起始值與常數的終止值
For...Next 迴圈 For...Next 迴圈的構成要件以及運作情形如下: 變數值的間隔大小,這裡可以使用正數或是負數。 正數的話,迴圈控制變數的值就會遞增。 負數的話,迴圈控制變數的值就會遞減。 沒有給,預設值是 1。 For I = 1 To 50 如果沒有給,預設值是 1 For I = 1 To 50 Step 3 正數的間隔值 I 的值將從 1、4、7、... 增加到 49、52 為止 For I = 50 To 10 Step -2 負數的間隔值 I 的值將從 50、48、... 遞減到 10、8 為止 For I = 50 To 10 Step X 間隔值也可以是數值變數
For...Next 迴圈 For...Next 迴圈的構成要件以及運作情形如下: 在 For...Next 迴圈中如果要提前結束迴圈的執行,可以利用「Exit For」,跳出迴圈。 「Exit For」通常跟「If...Then」一起使用。例如 If...Then 後面再執行 Exit For 。 For I = 1 To 30 x = x - 2 If x < 0 Then Exit For 變數 x 小於 0 時,就會離開迴圈 Next I Print x
For...Next 迴圈 使用 For...Next 迴圈的注意事項 For I = 30 To 20 x = x - 2 這一行永遠執行不到 Next I
For...Next 迴圈 使用 For...Next 迴圈的注意事項 當間隔值為正時,迴圈終止執行的條件是「迴圈控制變數大於終止值」。 For I = 3 To 10 迴圈終止的條件是 I > 10 For I = 10 To 1 Step -1 迴圈終止的條件是 I < 1
For...Next 迴圈 使用 For...Next 迴圈的注意事項 建議將迴圈控制變數名稱放在後面。好處是程式比較容易瞭解,當迴圈的結構很複雜時,也比較容易偵錯。 For I = 3 To 10 這樣的迴圈結構比較容易閱讀 For J = 10 To 1 Step -1 Print I, J Next J Next I
練習 For...Next 迴圈 計算 1 加到 100 的總和。 宣告兩個變數,一個是迴圈控制變數I 從1 遞增到 100。另一個就是計算總和的變數 Total。 Dim I As Integer Dim Total As Integer 起始值為 0 For I = 1 To 100 Total = Total + I Next I Print "1 + 2 + ... + 100 = "; Total
練習 For...Next 迴圈 利用一個迴圈同時計算 1 到 100 中,所有奇數的總和與所有偶數的總和。 宣告 oddtotal 與 eventotal 分別為奇數與偶數的總和。然後設定迴圈的間格數值是2。 Dim I As Integer, oddtotal As Integer Dim eventotal As Integer For I = 1 To 99 Step 2 oddtotal = oddtotal + I eventotal = eventotal + I + 1 Next I Print "1 + 3 + ... + 99 = "; oddtotal Print "2 + 4 + ... + 100 = "; eventotal
巢狀迴圈的使用 巢狀迴圈的基本結構 Dim I As Integer, J As Integer Print "I", "J" 1 5 1 6 1 7 2 5 2 6 2 7 3 5 3 6 3 7 Dim I As Integer, J As Integer Print "I", "J" For I = 1 To 3 外迴圈 For J = 5 To 7 內迴圈,I 每增加一次,J 會從 5 到7 Print I, J Next J Next I
巢狀迴圈的使用 九九乘法表 Dim I As Integer, J As Integer Print "*"; '輸出乘法符號 For J = 1 To 9 Print Format(J, "@@@"); Next J Print '換行 For I = 1 To 9 Print Format(I, "@"); Print Format(I * J, "@@@"); Print '換行 Next I
實例應用:選擇排序法 選擇排序法的精神就是「選擇」, 每一次從尚未排序的一堆數值中,選出最小的數然後跟尚未排序數值中的第一個位置互換。 這樣的操作一直持續到最後一個數值為止,我們就可以將所有數值由小而大地排列出來。
實例應用:選擇排序法
陣列的進階使用 多變的一維陣列 除了前面所介紹的陣列宣告方式外,以下也是 Visual BASIC 所提供的另外一種宣告語法: Dim 陣列名稱(下限值 To 上限值) [ As 資料型態] Dim Arr1(10) As Integer 宣告了陣列 Arr1 有 11 個元素,存取陣列 Arr1 的索引值從 0 到 10。 Dim Arr2(-5 To 5 ) As Integer 同樣的也是宣告了一個擁有 11 個元素陣列 Arr2,不過,存取陣列 Arr2 的索引值卻是從 -5 到 5。
陣列的進階使用 Visual BASIC 提供了取得陣列索引值的函數: LBound 函數顯示陣列的下限值 UBound 函數就是顯示陣列的上限值 Dim arr1(10) As Integer Dim arr2(-3 To 5) As Integer Print LBound(arr1), UBound(arr1) 輸出的結果是 0 與 10 Print LBound(arr2), UBound(arr2) 輸出的結果是 -3 與 5
Array 函數的使用 Visual BASIC 在陣列的使用上,有一個缺點 不能在宣告時由我們來設定陣列的初始值 為了彌補這個缺憾,Visual BASIC 提供了 Array 函數,它的功能是在設定初始值的同時,順便建立陣列。 陣列的預設下限值是「0」,利用 Array 所建立的陣列,第一個元素是放在編號 0 的位置內 Dim MyWeek, MyDay 一定要宣告為資料型態 Variant MyWeek = Array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") MyWeek 自動變成擁有 7 個元素的 Variant 陣列 MyDay = MyWeek(0) ' MyDay 的值為 Mon,陣列的編號預設從 0 開始 MyDay = MyWeek(3) ' MyDay 的值為 Thu。
Array 函數的使用 Array 函數所建立的陣列,它的資料型態必須是 Variant x = Array("一月", "二月", "三月", "四月", "五月", "六月", _ "七月", "八月", "九月", "十月", "十一月")
多維陣列 多維陣列的宣告 Dim 陣列名稱(索引值1,索引值2,...) [ As 資料型態] 多維陣列的宣告與限制基本上跟一維陣列是一樣的,每一個維度都可以使用「大小」或是「下索引值 To 上索引值 」的宣告方式。 二維陣列是我們最常使用的多維陣列
多維陣列 跟二維陣列性質最接近的就是表格,只要將表格的觀念用在二維陣列上,應該不難瞭解二維陣列的使用。
多維陣列 要存取二維陣列中的元素,跟一維陣列一樣,必須透過索引值。 計算九九乘法表的程式,利用一個 9x9 的二維陣列來儲存九九乘法表的內容 Dim X(9,9) As Integer, Y as Integer, Z as Integer Y = X(3,2) 將陣列第三列第二行中的值指定給 Y Z = X(2,1) + X(6,5) Dim X(9,9) As Integer For I = 1 To 9 For J = 1 To 9 X(I,J) = I * J Next J Next I 計算九九乘法表的程式,利用一個 9x9 的二維陣列來儲存九九乘法表的內容
多維陣列 一年 A 班有學生 25 人,利用陣列來儲存以下的資料:所有學生的國文、英文與數學成績,這三科的總成績以及平均成績。 Const Num_Stu = 25 '利用常數來簡化程式的設計 Dim Score(Num_Stu, 5) As Single Str1$ = "請輸入座號第 ": Str2$ = " 號同學的國文成績" Str3$ = " 號同學的英文成績": Str4$ = " 號同學的數學成績" For I = 1 To Num_Stu '根據座號依序輸入同學的成績 Score(I, 1) = Val(InputBox(Str1 & I & Str2))'輸入國文成績 Score(I, 2) = Val(InputBox(Str1 & I & Str3))'輸入英文成績 Score(I, 3) = Val(InputBox(Str1 & I & Str4))'輸入數學成績 Next I For I = 1 To Num_Stu For J = 1 To 3 '計算三科總成績 Score(I, 4) = Score(I, 4) + Score(I, J) Next J Score(I, 5) = Score(I, 4) / 3# '計算平均成績
多維陣列 設定陣列的索引初始值 如果覺得陣列索引的初始值,從 0 開始不太能適應,可以在程式中加入「Option Base 1」將下限設定 1,而不是預設值 0。 「Option Base 1」只能加在程式碼視窗中「一般」物件選單中的「宣告」程序中。
For...Next 的延伸 For Each...Next Dim A(2) As Integer Dim Idx As Variant A(0) = 5: A(1) = 10: A(2) = 15 For Each Idx In A Print Idx Next Idx
While...Wend 迴圈 While...Wend 的語法如下: 這是一個先判斷再執行的迴圈 While 條件判斷式 程式區段 當條件判斷式為「真」時,執行迴圈內的程式區段 迴圈內的程式區段會被一直執行,直到條件判斷式為「假」時,程式才會執行「Wend」後續的程式碼。 這是一個先判斷再執行的迴圈
While...Wend 迴圈 While...Wend 與 For…Next 的比較 Dim I, Total As Integer '數值變數的初值預設為 0 While I < 10 I = I + 1 Total = Total + I Wend Print "1+2+...+10 ="; Total 利用 For...Next 來執行同樣的工作 Dim I, Total As Integer For I = 1 To 10 Total = Total + I Next I
While...Wend 迴圈 While...Wend 迴圈適合用在不知何時會停止的任務上,比方說:根據使用者輸入的文字來結束程式的執行。 Dim Str1 As String While Str1 <> "Quit" Str1 = InputBox("請輸入文字,Quit 表示輸入完畢") Print "您輸入的是 "; Str1 Wend
Do While...Loop 迴圈 Do While...Loop 的語法如下 陳述區段 [Exit Do] Loop Do While...Loop 說是 While...Wend 迴圈的擴充 這個迴圈敘陳述只比 While...Wend ,多了一個離開迴圈的指令:「Exit Do」。
Do While...Loop 迴圈 Do While...Loop 迴圈有兩種不同的形式: Do While...Loop 除非While 後面的條件判斷式為「假」或是迴圈內有使用 Exit Do 強迫離開Do While...Loop 迴圈。 Do...Loop。這種迴圈,迴圈內的陳述區段會一直被執行,除非迴圈內有使用 Exit Do 強迫離開Do...Loop 迴圈。
Do While...Loop 範例:判斷使用者輸入的整數是否是 2 的倍數 IP_N = Val(InputBox("請輸入一個整數")): N = 0 Do While IP_N <> 1 tmp = IP_N Mod 2 If tmp = 0 Then 輸入的整數可以被 2 整除 N = N + 1: IP_N = IP_N / 2 Else 輸入的整數不能被 2 整除 Print "您輸入的整數不是 2 的倍數": Exit Do End If Loop If tmp = 0 Then Print 2 ^ N; "是 2 的 "; N; " 次方"
Do...Loop 範例:計算費氏級數 費氏級數就是目前的數值是由前兩個數值相加而得。 Do While...Loop 還有另外一個使用方式就是將 While 變成 Until,也就是 Do Until...Loop 迴圈。 I = 0: J = 1: Print J Do I = I + J: J = J + I: Print I: Print J If I > 10 Then Exit Do Loop Print "這是費氏級數"
Do Until...Loop Do Until...Loop 的語法: 迴圈執行的條件正好跟 Do While...Loop 相反。 陳述區段 [Exit Do] Loop Until 後面的條件判斷式為「假」時才執行迴圈內的陳述區段
Do Until...Loop 範例:計算階乘的程式 Do While...Loop 與 Do Until...Loop 迴圈都是先判斷再執行,不過執行迴圈的條件正好相反,不要弄錯了。 I = 1: J = 1 計算階乘的程式 Do Until I > 10 Print I; "! = "; J I = I + 1: J = J * I Loop Do While...Loop 當...為真時,執行迴圈內的陳述 Do Until...Loop 執行迴圈內的陳述,直到...為真時結束
Do...Loop Until 迴圈 Visual BASIC 允許將條件的測試移到迴圈的後面,形成先執行再判斷的迴圈,這就是 Do...Loop Until 迴圈。 語法如下: 只要條件判斷式為「假」時,Do...Loop Until 迴圈會一直執行下去,直到條件判斷式的值變成「真」為止。 Do 陳述區段 [Exit Do] Loop [Until 條件判斷式]
Do...Loop Until 迴圈 範例 計算階乘 I = 1: J = 1 Do Print I; "! = "; J I = I + 1: J = J * I Loop Until I > 10 計算費氏級數 I = 0: J = 1: Print J Do I = I + J: J = J + I Print I: Print J Loop Until I > 10
控制項陣列 認識控制項陣列 控制項陣列的建立 多個相同名稱的變數可以組合成陣列,那多個相同名稱的控制項所組合而成的當然就是控制項陣列囉! 相同的控制項使用不同的名稱,我們必須為每一個控制項設計不同的程式碼來控制這些控制項。 一旦相同的控制項變成控制項陣列,利用一套程式碼,透過陣列索引值的改變,我們就能輕鬆的控制項這些控制項了。 控制項陣列的建立 需要實際的操作才能了解