880 likes | 1.17k Views
VB6 陣列與副程式. 陣列 (Array). 假設,當我們要連續輸入全班 25 位同學的各科成績時,在之前教過的方法中,我們可以宣告單一變數的方式宣告 — 國文 chi ,英文 eng ,數學 math ;當輸入並計算完第一位同學的成績後,緊接著輸入第二位同學 … 第三位同學 … 一直到第 25 位同學,很高興都計算完,此時問題來了,倘若此時要你查詢某位同學的各科成績,並在螢幕上顯示出來,你該如何?. 請問第二位的成績在哪裡?. 陣列 ( 續 ). chi. eng. math. 陣列 ( 續 ).
E N D
陣列(Array) • 假設,當我們要連續輸入全班25位同學的各科成績時,在之前教過的方法中,我們可以宣告單一變數的方式宣告—國文chi,英文eng,數學math;當輸入並計算完第一位同學的成績後,緊接著輸入第二位同學…第三位同學…一直到第25位同學,很高興都計算完,此時問題來了,倘若此時要你查詢某位同學的各科成績,並在螢幕上顯示出來,你該如何?
請問第二位的成績在哪裡? 陣列(續) chi eng math
陣列(續) • 為達目的,因此我們不擇手段地連續使用chi1~chi5、eng1~eng5、math1~math5這些變數來儲存各項成績 • 問題來了,雖然每個數值都存在記憶體中,要找第二個同學的成績時,程式設計又是一個繁複的問題
這樣的設計方式,是不是很驢?5個同學還好,25個同學或更多的話,程式何時了?這樣的設計方式,是不是很驢?5個同學還好,25個同學或更多的話,程式何時了? 陣列(續) Select Case sel Case 1 Text1.Text=chi1 Text2.Text=eng1 Text3.Text=math1 Case 2 Text1.Text=chi2 Text2.Text=eng2 Text3.Text=math2 : : Case 5 Text1.Text=chi5 Text2.Text=eng5 Text3.Text=math5 End Select 不管有多少學生,能以3行程式就 取代這麼驢的方式,何樂而不為? Text1.Text=chi(sel) Text2.Text=eng(sel) Text3.Text=math(sel)
索引值 陣列(續) • 陣列就是 • 容許使用同一個名稱來處理多個數值 • 一群性質相同的資料數值的集合 • 亦即,其所含有之元素皆具有相同的型別,因此在一個陣列中同時含有整數與文字是不可能的 • 所以,陣列為存放在連續記憶體中某一型態變數值的集合
陣列(續) • 陣列中的每個元件相當於一個變數,在陣列中存取變數只需要指定索引值即可 • 陣列使用前是必須宣告的 • 語法 • 功能 • 宣告為所指定資料型態的一維(二維…)陣列 Dim 陣列名稱(索引1[,索引2[……]]) [As 資料型態] Dim chi(25),eng(25),math(25) As Integer Dim student(25,3) As Single
陣列(續) • 如果我這樣宣告,記憶體會如何配置? Dim height(5) As Single 實際上在主記憶體裡配置了連 續6個連續位置來存放height(0) 到height(5)元件
陣列(續) • 前一張投影片告訴我們,一維陣列宣告後,其索引值是從0開始,有些人並不習慣這要的開頭,既然宣告陣列大小為5,又何必預留6個位置?假如從1開始到5,不是正好符合我們的宣告大小嗎? • Option Base Option Base 1 Dim p(3) p(1), p(2), p(3) Option Base 0 Dim p(3) p(0), p(1), p(2), p(3)
陣列(續) • Dim 陣列名稱 (上界 To 下界[,上界 To 下界…]) [As 資料型態] 如果這樣表示上表,會不會覺得很彆扭? Dim X(10) As Integer X(0)=25, X(1)=16, X(2)=9, X(3)=4, …, X(10)=25 順眼多了吧! Dim X(-5 To 5) As Integer X(-5)=25, X(-4)=16, X(-3)=9, X(-2)=4, …, X(5)=25
陣列(續) Dim name(5) As String name(0)=“蘇光裕” name(1)=“蘇光志” name(2)=“蘇光旭” name(3)=“蘇光遠” name(4)=“蘇光武” name(5)=“蘇靜怡” • 宣告陣列後,若要指定起始值給陣列,可以用右列的方法 • 或是 • Array函數 自由型態變數 Dim name As Variant name=Array(“蘇光裕”, “蘇光志”, “蘇光旭”, “蘇光遠”, “蘇光武”, “蘇靜怡”) Dim student As Variant name=Array(“蘇光裕”, 173, 75.6) 既然是自由型態變數,資料型態就可跳脫陣列中只能儲存相同型態資料的限制
陣列(續) • For Each … Next 陣列迴圈 • 語法 • 功能 • 以所指定的陣列元件數目,重複執行某個敘述區段 For Each 變數 In 陣列名稱 [敘述區段] [Exit For] Next Dim name As Variant name=Array(“蘇光裕”, “蘇光志”, “蘇光旭”) For i=0 to 2 Print name(i) Next i Dim name As Variant name=Array(“蘇光裕”, “蘇光志”, “蘇光旭”) For Each i In name Print i Next i 左右兩種寫法結果是相同的
陣列(續) • 二維陣列 • 一個陣列若具有兩個索引稱為二維陣列 • 常用於數學的矩陣、學生成績單、各式報表… • 可將其視為由列(row)及行(column)組合而成的資料表單 • 語法 • Dim 陣列名稱(索引1, 索引2) [as 資料型態] • 功能 • 宣告為二維陣列
陣列(續) • 有時候在程式執行了一段時間後,才能決定陣列的大小,無法在程式一開始執行時決定,此時該如何是好? • 動態陣列宣告 • 在程式未執行前並未配置任何記憶體給該陣列,而是等到程式執行到該宣告時,才會要求系統配置記憶體給該陣列使用 • 以Dim來宣告空維數陣列 • 再以ReDim來宣告大小以配置元件的數目 Dim height() As Single n為任意整數 ReDim height(n) As Single
陣列(續) • 清除陣列 • 以往清除陣列的方式 • 以Erase清除陣列內容 • 語法 • Erase 陣列名稱 • 功能 • 使用Erase可將動態陣列釋放掉或將靜態陣列清為預設值 For i=0 to 10 aa(i)=0 Next i Erase aa
牛刀小試(1) • 設計一程式,完成兩個陣列相加的動作 • 必須是相同規格的陣列才可進行相加的動作 + = +
牛刀小試(1)—續 Text1(0)~Text1(8) Text2(0)~Text2(8) 偷懶的寫法 Text3(0)~Text3(8) Command1
牛刀小試(2) • 設計一程式,完成兩個陣列相加的動作
j的值比i的值先變,所以 j要放在內層迴圈,i要放 在外層迴圈 牛刀小試(2)—續 i i i = + j i j i j i j i j i j i j i j i j i j C(1,1)=A(1,1)+B(1,1)C(1,2)=A(1,2)+B(1,2)C(1,3)=A(1,3)+B(1,3) C(2,1)=A(2,1)+B(2,1) C(2,2)=A(2,2)+B(2,2) C(2,3)=A(2,3)+B(2,3) C(1,1)=A(3,1)+B(3,1) C(3,2)=A(3,2)+B(3,2) C(3,3)=A(3,3)+B(3,3)
牛刀小試(2)—續 宣告未知大小的三個陣列A, B, C 並輸入 陣列的行、列大小,重新宣告陣列A, B, C 以InputBox依序輸入陣列A的 值,並將其值列印於Form上 以InputBox依序輸入陣列B的 值,並將其值列印於Form上 將陣列A與陣列B相同位置的值相加後,其 值指派給陣列C的相同位置上,並將其值列 印於Form上
牛刀小試(3) • 設計一程式,完成兩個陣列相乘的動作 • A、B兩陣列要能相乘,必須令A的行與B的列相等,亦即A(i,j)*B(j,k)=C(i,k) 4*7+5*1+6*5 =28+5+30=63 + 4 5 6 7 8 9 1 2 3 + 7 2 1 8 5 3 63 66 102 105 24 27 = *
j先變,k次之,i最後變 牛刀小試(3)---續 m1 m2 m3 4 5 6 7 8 9 1 2 3 7 2 1 8 5 3 63 66 102 105 24 27 = * j*k i*j i*k i k i j j k i j j k i j j k m3[0][0]=m1[0][0]*m2[0][0]+m1[0][1]*m2[1][0]+m1[0][2]*m2[2][0] m3[0][1]=m1[0][0]*m2[0][1]+m1[0][1]*m2[1][1]+m1[0][2]*m2[2][1] : :
牛刀小試(3)---續 宣告未知大小的三個陣列A, B, C 並輸入 陣列的行、列大小,重新宣告陣列A, B, C 以InputBox依序輸入陣列A的 值,並將其值列印於Form上 以InputBox依序輸入陣列B的 值,並將其值列印於Form上 將陣列A與陣列B相關位置的值相乘後,其 值指派給陣列C的相關位置上,並將其值列 印於Form上
牛刀小試(4) • 設計一程式,完成兩個陣列相乘的動作
牛刀小試(5) • 設計一程式,可輸入全班同學成績,並計算平均與總分
牛刀小試(5)---續 Label*6 TextBox*6 (Text1*1, Text3*5) Picture1的屬性AutoRedraw=True PictureBox*1
牛刀小試(5)---續 宣告一個未知大小的陣列list及學生編號的變數snum 程式一執行先令snum=0 當Text1的內容輸入後按下Enter鍵時,重新宣告list為二維變數,型態為自由型態,讓Text3(0)~(4)的Enabled屬性設為True,控制權交給Text3(0) 當Text3的內容輸入後按下Enter鍵時,依序將控制權交給下一個Text3陣列,直到“數學”輸入完後,作動Command1,並將控制權交給Command1
牛刀小試(5)---續 當成績輸入完按下Command1後,將資料記錄 於list的二維陣列中(包含座號、姓名、各科成 績、總分及平均) ,同時讓Command1停止作 動功能。記錄完後清空所有Text3文字盒的內 容,並將控制權交給Text3(0) 亦即,代表 座號的文字盒 用Print方法將成績結果顯示於 Picture1上 假如要查詢學生成績時,輸入學號後,先判 段是否有此學號,若有,則將此學生的成績 顯示於Text3(0)~(4)的Text屬性中
副程式(Subprogram) • 撰寫程式時,將某一段具有特定功能的敘述區段單獨抽取出來,另行編寫成程式單元,給予特定名稱,以方便其他程式的呼叫使用 • 種類 • 內建函數(Built-in Function) • 程序(Procedure) • 事件程序 • 一般程序 • Sub … End Sub • Function … End Function • 次常式(GoSub…Return)
副程式(續) • Sub程序 • 語法 [Private | Public][Static] Sub 程序名稱 [(引述串列)] : : [程式區段] : : [Exit Sub] : End Sub Public Sub Sqrt(a As Integer, b As Single) b= a ^.5 End Sub
副程式(續) Priavate Sub Command1_Click() Call Sqrt(25,y) Print y End Sub Public Sub Sqrt(ByVal a As Integer, ByVal b As Single) b= a ^.5 End Sub • 呼叫副程式 • Call敘述 • 語法 1. Call 程序名稱[(引述串列)] Call Sqrt(25,y) 2. 程序名稱[(引述串列)] Sqrt(25,y)
牛刀小試(6) • 試設計一程式,以副程式方式設計九九乘法表
副程式(續) • Function程序 • 語法 [Private | Public][Static] Function 函數名稱 ([引述串列])[As 資料型態] : : [程式區段] : : [Exit Function] : End Function
副程式(續) • 呼叫函數 變數名稱=函數名稱([引數串列])
三角函數的使用 • VB所提供的三角函數 • Sin(弳度) • Cos(弳度) • Tan(弳度) 角度轉換為弳度的公式 弳度=(角度) ×( / 180 ) 角度 弳度 30o 30*(3.14159/180)0.523598
副程式(續) • 次常式(Subroutine) • 語法 • 呼叫次常式 標記: [敘述區域] Return 行號 [敘述區域] Return 或 GoSub {標記 | 行號}
牛刀小試(7) • 試以次常式方式設計一繪製同心圓個數的程式
參數傳遞的方式 • 傳值呼叫(Call by Value) A B C D 23 51 23 51 : A=23:B=51 Call nn(A,(B)) : Private nn(ByValC As Integer, D As Integer)
參數傳遞的方式(續) • 傳址呼叫(Call by Address/Reference) 1000 1002 1004 1006 1008 1010 A B C D 23 51 : A=23:B=51 Call nn(A,B) : Private nn(ByRefC As Integer, ByRefD As Integer)
範例一(選擇排序法) • 是目前最簡單的排序方法之一 • 步驟 • 從全部N個資料中,選取最小的一個將它與陣列中第一個位置的數字交換 • 從剩下的N-1個資料中,選取最小的一個將它與陣列中第二個位置的數字交換 • 從剩下的N-2個資料中,選取最小的一個將它與陣列中第三個位置的數字交換 • … • 一直做到只剩下一個資料為止
宣告空陣列List,決定數列中的數字 個數,重新宣告List陣列,並依序輸 入數列數值 範例一(續) 將所輸入的數列列印於螢幕上 呼叫選擇排序副程式 將排序後的數列列印於螢幕上 令數列的第i個值為最小值 依序拿i+1及其後的數值與最小值比較 假如小於最小值,則最小值更換為此數 並與第i個數值互換
範例二(泡沫排序法) • 最簡單的一種排序方法 • 步驟 • 從第一個數字開始,依序將兩個相鄰的數值兩兩互相比較大小 • 如果前一個比後一個大,互相交換位置 • 一直做到每一對相鄰的數字都比較過後才結束這一輪工作 • 回到第一步,再做新一輪的比較工作,如果有N個數字要來排序,就必須重複N-1次的掃描工作
考慮 範例二(續) For i=n-1 To 1 Step –1 For j=1 To i If list(j)>list(j+1) Then temp=list(j) list(j)=list(j+1) list(j+1)=temp End If Next j Next i
temp list j j+1 範例二(續) 6 3 6 1 • 程式的精神所在 Private Sub Bubble_Sort( list() as Single ) For i=1 To n-1 Step -1 For j=1 to i If list(j) > list(j+1) Then temp=list(j) list(j)=list(j+1) list(j+1)=temp End If Next j Next i End Sub 2 temp list j j+1 3 6 3 6