「姊姊從早上第一節上課到第七節下課才放學回家」、「爸爸昨天加班到晚上十點才下班(就是一直工作到十點才停止)」、「妹妹已經會從
1 數到10了」,以上都是我們日常生活中,常見重複做事的形式。這些工作都有開始、結束以及重複的過程。電腦最方便的就是它可以重複做相同的事,尤其是無聊的事。本章要介紹幾種讓電腦重複做事的程式。電腦做重複工作時也有開始、結束以及重複的過程。我們把電腦重複的過程叫做「迴圈」。
4-1使用For…Next
從
1顯示到10如果沒有迴圈這種指令可以使用,就只好
Print 1、Print 2、…一直寫到Print 10,萬一要顯示到10000,那就會累死人。還好我們可以用For Next指令,要從1顯示到10只須寫如下的程式碼就可以了,是不是簡單多了呢!For I=1 To 10
Print I
Next I
在這段程式碼裡,
I是一個變數,它控制著迴圈的結束與否。For、To、Next都是關鍵字,1是起始值,10是終止值。從For到Next I,稱為迴圈,第一列For I=1 To 10可以讀成「I從1到10」,所以經過這一列程式碼之後I值為1,第二列Print I,將於表單上顯示I的內容(就是1)。第三列Next I,可以讀成「下一個I」,把I的值加1後回到第一列檢查I的值是否超過10(目前I=2),如果沒有超過,就繼續執行第二列、第三列,直到超過10為止。從
1加到N底下示範的專案,使用者輸入一個數字,然後顯示從
1加到他所輸入數字的和,表單設計如下:
Name |
Caption |
Text |
|
文字方塊 TextBox |
txtN | ||
命令鈕 CommandButton |
cmdDo | 確定 | |
標籤 Label |
lblAns |
當使用者按下「確定」鈕時,以底下的程式處理:
Private Sub cmdDo_Click()
Dim N As Integer
Dim I As Integer
Dim Sum As Long
N = txtN.Text
For I = 1 To N
Sum = Sum + I
Next
lblAns.Caption = Sum
End Sub
N是使用者輸入的數字,在迴圈中,I值從1到N,每次都累加到Sum裡,這樣Sum就是從1加到N的總和了。執行結果如下:
圖
4-2執行結果 (1ToN.Vbp)Step
怎樣讓迴圈的變數值每次增加
2呢?我們可使用Step這個關鍵字。例如要顯示1、3、5…、11,就可以用如下的程式碼:For I=1 To 11 Step 2
Print I
Next I
Step後面的數字,表示I值每次遞增的值。程式進入第一列程式碼時,I值為1,第二列顯示出1,第三列取得下一個I,因為I每次要增加2所以I值就變成3了,回到第一列看看是否超過11,如果沒有超過就繼續執行。
底下我們要示範一個專案,可以讓使用者輸入數字,然後由程式輸出從1到這個數字的奇數連乘積。表單上安排一個文字方塊供使用者輸入數字,安排一個命令鈕,點選後可以在標籤上輸出結果。表單設計如下:
屬性值設定如下:
Name |
Caption |
Text |
|
文字方塊 TextBox |
txtN | ||
命令鈕 CommandButton |
cmdDo | 確定 | |
標籤 Label |
lblAns |
程式碼設計時,首先將使用者輸入的數字讀入
N中,然後看看N是否大於0,另外看看N是否為奇數,如果這兩個條件都符合才開使用迴圈計算乘積。在For迴圈中,我們使用Step 2,使得I值為1,3,5...的奇數值。程式碼如下:Private Sub cmdDo_Click()
Dim N As Integer
Dim I As Integer
Dim Sum As Long
N = txtN.Text
If N > 0 And N Mod 2 = 1 Then ‘
當N>0 而且為奇數時Sum = 1
For I = 1 To N Step 2
Sum = Sum * I
Next
lblAns.Caption = Sum
Else
lblAns.Caption = "
輸入正奇數"End If
End Sub
Sum=1的原因是在程序中Sum的初始值是0,所以連加時不會產生錯誤,但是連乘時,如果Sum的初始值是0,那麼結果一定是0,這是必須要注意的。
執行結果如下:
圖
4-4 Time1 To N.vbp執行結果如果執行時輸入
21以上就會產生溢位的錯誤,您可以將long型態改成single或double得到更大的數值範圍。使用
For…Next的注意事項For I= 5 To 1 Step –1
Print I
Next I
For I=1 To 5 Step –1
Print I
Next I
For I=5 To 1
Print I
Next I
4-2使用ScrollBar
ScrollBar的中文叫做捲軸,又可以分為垂直捲軸和水平捲軸。我們可以用ScrollBar當做數字輸入的控制項。
用
ScrollBar輸入數字捲軸的
Value屬性,可以用移動捲軸上的柱狀游標來改變,也可以點選箭號按鈕或柱狀游標和箭號鈕之間的空白來改變。Value屬性值的最大值設定在Max屬性中,最小值設定在Min屬性中。如果要讓使用者輸入
1到300之間的數字,就可以將捲軸的Max屬性值設定為300,Min屬性值設定為1。當捲軸的Value屬性改變時,產生Change事件,我們可以在Change事件中撰寫使用者輸入數字後要做的事情。底下的專案為您示範使用水平捲軸輸入
1到300之的數字,安排一個水平捲軸,改變後可以在標籤上輸出輸入的值。在工具箱中點選屬性值設定如下:
Name |
Caption |
|
水平捲軸 HScrollBar |
hsbN | |
標籤 Label |
lblN |
當使用者改變捲軸時,產生
Change事件,我們在此事件中顯示捲軸的Value值。程式碼如下:Private Sub hsbN_Change()
lblN.Caption = hsbN.Value
End Sub
執行結果如下:
圖
4-6執行結果 (Scroll.Vbp)當我們點選箭號鈕時,
Value值依照SmallChange所設定的值改變,當我們點選箭號鈕和柱狀游標之間時,Value值依照LargeChange所設定的值改變,請您改一改SmallChange屬性和LargeChange屬性,看看變化。
計算
1 TO N的和底下的專案為您示範讓使用者用捲軸輸入
1到32767之間的數值,一旦輸入就改變計算的結果(不需要按下命令鈕),我們使用PictureBox輸出結果,PictureBox的中文叫做圖片方塊,安排圖片方塊要在工具箱中點選屬性值設定如下:
Name |
Caption |
Min |
|
標籤 Label |
lblN | N=1 | |
水平捲軸 HScroll Bar |
hsbN | 1 | |
圖片方塊 PictureBox |
picOutput |
當使用者改變捲軸值時,程式要在圖片方塊顯示結果,圖片方塊輸出的方式和表單類似,也就是使用
Print,只是要在Print的前面加上物件的名稱。程式碼如下:Private Sub hsbN_Change()
Dim i As Long
Dim S As Long
lblN.Caption = "N=" & hsbN.Value
picOutput.Cls
picOutput.Print "
計算 1 到 " & hsbN.Value & " 的值"S = 0
For i = 1 To hsbN.Value
S = S + i
Next
picOutput.Print "
答案是 " & SEnd Sub
用
Print輸出於表單上時不用加上表單的名稱是省略的寫法,加上表單的名稱也不會錯,注意:物件名稱和Print之間用.連起來。執行結果如下:
圖
4-9執行結果 (Cal1ToN.Vbp)顯示階乘值
N階乘寫成N!,意思是從1開始連乘到N,也就是1*2*…*N的值,底下的專案為您示範顯示從1到使用者輸入數值的階乘值表,一旦輸入改變,輸出的階乘表也會跟著改變),我們使用PictureBox輸出結果。表單設計如下:
屬性值設定如下:
Name |
Caption |
Text |
|
標籤 Label |
lblN | ||
水平捲軸 HScroll Bar |
hsbN | ||
圖片方塊 PictureBox |
picOutput |
當使用者改變捲軸值時,程式要在圖片方塊顯示結果,我們仍然以
For…Next來撰寫主要的迴圈,因為階乘的數字非常大,所以計算總積的變數改用Double型態(Basic裡Double型態可以表示到最大的數值)。程式碼如下:Private Sub hsbN_Change()
Dim i As Integer
Dim S As Double
lblN.Caption = "N=" & hsbN.Value
picOutput.Cls
S = 1
For i = 1 To hsbN.Value
S = S * i
picOutput.Print i & "! = " & S
Next
End Sub
執行結果如下:
圖
4-11執行結果 (TimeN.Vbp)當我們把數值加大時,階層表中數字較大的就看不到了,我們可以用加大表單和圖片方塊的方式讓顯示的數量增加,不過這樣的方式所能顯示的數量還是有限的。底下示範只要在程式碼中稍加修改,就可以看到數值中較大的部份。
Private Sub hsbN_Change()
Dim i As Integer
Dim S As Double
lblN.Caption = "N=" & hsbN.Value
picOutput.Cls
S = 1
For i = 1 To hsbN.Value
S = S * i
If i > hsbN.Value - 13 Then
picOutput.Print i & "! = " & S
End If
Next
End Sub
因為本專案的圖片方塊中只能顯示
13列,所以顯示前先檢查「I」值是否比「N值減13」還大,如果是才顯示出來,這樣就可以顯示較大數值的階層表了。執行時,您可以按住捲軸 鈕,看起來文字在圖片方塊中捲動。執行結果如下:圖
4-12執行結果(TimeN2.Vbp)4-3使用While…Wend
While是當某一條件成立時就在迴圈內不斷執行的結構。這種迴圈,和For一樣不一定會執行:當條件一開始就不合時,迴圈將不會執行。
While
和For迴圈如果用
While迴圈顯示1到10,可以用底下的程式碼來完成:I=1
While I<=10
Print I
I=I+1
Wend
While後面的運算式用來判斷迴圈什麼時候執行,在本範例中為I<=10,也就是當I小於或等於10時,將會重複執行到Wend的位置,Wend(看成While的End)是While迴圈結束的位置。
Print I可以將I值顯示出來,I=I+1就相當於Next I時將I的值增加1,使得程式有機會離開迴圈,當I增加到11時,因為I<=10已經變成False了,此時程式就執行Wend以後的程式碼。
最大公因數
底下示範使用
While迴圈,求得兩數的最大公因數。首先我們在表單上安排兩個文字方塊輸入兩個數字,安排一個命令鈕,當命令鈕被按下時在標籤上顯示最大公因數。表單設計如下:屬性值設定如下:
Name |
Caption |
Text |
|
文字方塊 TextBox |
txtN1 | ||
文字方塊 TextBox |
txtN2 | ||
命令鈕 CommandButton |
cmdOutput | 輸出 | |
標籤 Label |
lblInput | 輸入 | |
標籤 Label |
lblOutput |
我們在
Click事件中,撰寫輸出的程式碼:首先將兩個數值讀入N1和N2之內,然後使用輾轉相除法求出最大公因數,輾轉相除法的原理是:大數去除以小數,如果無法除盡,就把大數的餘數變成小數,原來的小數變成大數,然後再繼續去除,直到其中一數的餘數是0為止,此時剩下的另一個餘數就是最大公因數。程式先檢查
N1是否小於N2,如果是就將N2和N1交換,然後檢查餘數是否為0,如果不是0就進入While迴圈,將小數指定給大數,餘數指定給小數繼續求餘數,直到餘數是0為止。(程式碼中N1是大數,N2是小數)程式碼如下:執行後的結果如下:
圖
4-14 執行結果(Fact3.Vbp)何時存款變兩倍
銀行存款通常以複利計息,也就是第二年時,第一年的利息將滾入本金,計算利息。底下示範使用
While迴圈,讓使用者輸入利率(5%~10%),輸出幾年後存款會變成原來的兩倍。由於利率限定於
5%~10%,所以用捲軸來輸入,我們將捲軸Min的和Max分別設定為500和1000,這樣捲軸的Value值就可以從500~1000,將捲軸的值除以100,就可以得到5、5.01、5.02、…、10,這樣就符合利率的要求了。表單設計如下:
屬性值設定如下:
Name |
Caption |
Text |
|
捲軸 HScorllBar |
hsbN | ||
標籤 Label |
lblRate | 利率=5% | |
標籤 Label |
lblYear |
我們在捲軸的
Change事件中,撰寫輸出的程式碼:首先將捲軸的Value值轉換成利率,顯示於標籤上,然後用While迴圈算出幾年可以變成兩倍:S是我們假設的本金,開始時為1,所以當S>=2時就變成兩倍以上了,While後面的運算式為S<2表示S還沒有變成兩倍時,要進行迴圈內的程式。將
Value屬性除以10000就可以得到利率。S = S + hsbN.Value/10000就是將本金和利息變成下一年的本金。每進入迴圈一次就將i值1,表示經過了一年,所以當S變成兩倍時,輸出i就可以了。程式碼如下:Private Sub hsbN_Change()
Dim i As Integer
Dim S As Double
lblRate.Caption = "
利率=" & hsbN.Value / 100 & "%"S = 1
While S < 2
S = S + S * hsbN.Value / 10000
i = i + 1
Wend
lblYear.Caption = "
需要" & i & "年"End Sub
執行後的結果如下:
圖
4-16執行結果(Money.Vbp)4-4使用Do…Loop
Do…Loop程式也是一種迴圈結構,它有兩種形式。
Do
…Loop的兩種形式Do…Loop的兩種形式是:
I=1
Do Whlie I<=10
Print I
I=I+1
Loop
本段程式碼和使用
While…Wend的完全相同,也就是兩種程式碼可互換。I=1
Do
Print I
I=I+1
Loop While I<=10
Do…Loop的條件式有While形式和Until形式兩種:
I=1
Do Until I>10
Print I
I=I+1
Loop
用
Do…Loop求最大公因數之前我們介紹用輾轉相除法來求最大公因數,接下來,我們將以
Do…Loop的方式來求最大公因數(程式的設計不是只有一種方式)。假設有N1、N2兩個數,且N1>=N2,那麼我們可以設定一個變數I,從N2開始,每次減1,不斷的測試N1除以I和N2除以I,直到N1除以I和N2除以I都是0,此時的I值就是這兩個數的最大公因數。表單和上一個求最大公因數的表單完全相同,程式碼如下:
4-5中途離開迴圈
使用
Exit我們可以使用
Exit For離開For Next的迴圈,使用Exit Do離開Do Loop的迴圈。(Visual Basic沒有離開While…Wend迴圈的指令,但是您可以將While…Wend轉換為Do While…Loop。)下面的程式碼,當
I=3時就離開迴圈了(只能顯示出1、2、3):For I= 1 To 10
Print I
if I=3 Then Exit For
Next I
下面的程式碼,當
K=3時離開迴圈:Do Until False
K=K+1
If K=3 Then Exit Do
Print K
Loop
以上的程式碼如果沒有
Exit Do,那就變成無窮的迴圈,因為Until False是不會成立的。是否為質數
Exit Do和Exit For時常用於找尋資料時,當資料找到了就立刻跳出迴圈。底下要示範檢查一個數字N是否為質數,質數就是一個數字除了它自己和1以外沒有其它的因數,所以可以從2到N-1的每一個數字去尋找,如果找到一個數字它可以被N整除,那麼N就不是質數,否則是質數。我們可以在找到被整除的數字時就離開迴圈。
事實上,我們要尋找的數字應該到就可以了,因為
以前的數字不是N的因數的話,那麼從
到N-1也不會有N的因數了。
我們在表單上安排一個文字方塊供輸入數字,按下命令鈕將結果顯示於標籤上,表單設計如下:
屬性值設定如下:
Name |
Caption |
Text |
|
文字方塊 TextBox |
txtInput | ||
命令鈕 CommandButton |
cmdDo | 確定 | |
標籤 Label |
lblOutput |
我們必須撰寫按下「確定」鈕的程式碼,程式碼如下:
Private Sub cmdDo_Click()
Dim intI As Integer
Dim intNum As Integer
Dim blnFind As Boolean
intNum = txtInput.Text
intI = 2
blnFind = False
For intI = 2 To intNum ^ 0.5
If intNum Mod intI = 0 Then
blnFind = True
Exit For
End If
Next intI
If blnFind Then
lblOutput.Caption = intNum & "
不是質數"Else
lblOutput.Caption = intNum & "
是質數"End If
End Sub
執行結果如下:
圖
4-18 Prime.Vbp執行結果如果迴圈內有其他的迴圈,就叫做巢狀迴圈。
巢狀迴圈的流程
下面是一個簡單的巢狀迴圈:
當
I為1時,J要從11到12,也就是要顯示『1,11』和『1,12』兩列,當I為2時,J也要從11到12,也就是要顯示『2,11』和『2,12』兩列,當I為3時,J也要從11到12,也就是要顯示『3,11』和『3,12』兩列。再介紹
Print這個指令,Print可以將運算式的結果顯示出來,如果您要顯示兩個以上的運算式,先前我們用兩個Print寫成兩列的程式碼。不過我們也可以用;將兩個運算式的結果顯示在同一列上。例如:Print 16*3 ; 24 -12
這樣就會在同一列上顯示
『48 12』,如果把程式碼拆開成為兩列,寫成如下的樣子,結果也相同:Print 16 * 3 ;
Print 24 –12
也就是當
Print的後面接著「;」號時,就不會跳到下一列。如果您不想顯示任何東西,但是要將顯示的位置換到下一列,就可以只用Print,將顯示的位置跳到下一列。(Print後面不加;號及運算式)底下的程式碼可以顯示出一列
5個*號的圖案:For I=1 To 5
Print “*”;
Next I
如果您在外面增加一個迴圈,想要顯示五列,每一列都是
5個*號的圖案,而把程式撰寫如下:For J=1 To 5
For I=1 To 5
Print “*”;
Next I
Next J
您得到的不是五列,而是一列
25個*號的圖案,因為顯示5個*號後必須先往下跳一列。所以程式碼必須修正為:For J=1 To 5
For I=1 To 5
Print “*”;
Next I
Next J
顯示圖案
底下示範使用兩層
For迴圈,配合Print顯示三角形圖案。首先我們在表單上安排一個水平捲軸和一個圖片方塊,當捲軸的Value改變時,顯示圖案。表單設計如下:圖
4-19表單設計 (Pict1.Vbp)屬性值設定如下:
Name |
Min |
Max |
|
捲軸 HScrollBar |
hsbN | 1 | 13 |
圖片方塊 PictureBox |
picDraw |
Print指令的後面可以加上Spc( ),表示要空下幾個字元後才顯示,例如:
Print Spc(5);”*”
就會在*號前面空下
5個空格。我們在
Change事件中,撰寫輸出三角形的程式碼,就是用Spc( )空出不屬於三角形的空白部份,並利用Print的;號控制是否跳到下一列,程式碼如下:Private Sub hsbN_Change()
picDraw.Cls
For I = 1 To hsbN.Value
picDraw.Print Spc(hsbN.Value + 1 - I);
For J = 1 To I * 2 - 1
picDraw.Print "*";
Next J
picDraw.Print
Next I
End Sub
執行後的結果如下:
圖
4-20 執行結果 (Pict1.Vbp)九九乘法表
迴圈的層數是沒有限制的,底下將示範利用三層的
For…Next迴圈撰寫九九乘法表,我們開啟一個新的專案,在表單上不放任何的控制項,直接用表單輸出結果。使用表單輸出結果時,程式碼通常撰寫於Form_Paint事件中,程式碼如下:Private Sub Form_Paint()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Cls
For i = 1 To 7 Step 3 '
產生1,4,7For j = 1 To 9
For k = i To i + 2 'i=1
產生1,2,3 i=4 產生4,5,6Print k; "X"; j; "="; k * j,
Next
Print '
跳至下一列的列首Next
Print '
顯示空白列Next
End Sub
Print後面如果接的是「,」號時,表示顯示的位置要稍微跳一段距離(約15個字元),執行後可以得到如下的結果。您可以把表單放大,就可看到完整的乘法表。
將滑鼠移動到表單的邊框,然後拉大就可以看到完整的乘法表。
圖
4-21 9Table.Vbp執行結果巢狀迴圈的注意事項
4-7綜合範例
質因數分解
專案目標:輸入一個正整數,顯示它的質因數連乘積,例如:
12=2*2*3,15=3*5。表單設計:用一個文字方塊輸入正整數,輸出部份使用標籤,另外使用命令鈕計算結果。
屬性設定:
Name |
Caption |
Text |
BorderStyle |
|
文字方塊 TextBox |
txtN | |||
命令鈕 CommandButton |
cmdOutput | 輸出 | ||
標籤 Label |
lblInput | 輸入 | 1-單線固定 | |
標籤 Label |
lblOutput | 1-單線固定 |
程式設計:
程式解說:
執行結果:
圖
4-23範例一執行結果(Demo1.Vbp)尋找阿姆斯壯數
專案目標:使用者按下「確定」鈕後,找出所有三位數的阿姆斯壯數,將其顯示出來。阿姆斯壯數是三個數字的立方和恰好等於這個數字。
表單設計:安排一個命令鈕和圖片方塊。
屬性設定:
Name |
Caption |
Text |
BorderStyle |
|
命令鈕 CommandButton |
cmdDo | 確定 | ||
圖片方塊 Label |
picOutput | 1-單線固定 |
程式設計:
Private Sub cmdDo_Click()
Dim A As Integer
Dim B As Integer
Dim C As Integer
?
For A = 1 To 9For B = 0 To 9
For C = 0 To 9
?
If 100 * A + 10 * B + C = A ^ 3 + B ^ 3 + C ^ 3 Then?
picOutput.Print A & B & CEnd If
Next C
Next B
Next A
End Sub
程式解說:
執行結果:
圖
4-25 尋找阿姆斯壯數執行結果(Demo2.Vbp)習題