一個在駭客界引起轟動的菜鳥教材---跟我學程式設計系列(轉)

BSDLite發表於2007-08-12
一個在駭客界引起轟動的菜鳥教材---跟我學程式設計系列(轉)[@more@]跟我學程式設計系列

原黑白新區記憶碎片的帖子!轉貼上來,供大家學習!!!



發現大部分黑白的朋友都不會程式設計, 這可不是件好事, 所以這次我就寫了一個簡單的程式設計教程, 講一下VBScript. 主要面向菜鳥, 懂得程式設計的朋友就不要浪費時間了, 如果你想接觸以下VBScript也可以, 但既然有程式設計基礎推薦直接去找一些參考書來讀, 會比較快.

什麼是VBScript呢? VBScript的全稱是:Microsoft Visual Basic Script Editon.(微軟公司視覺化BASIC指令碼版). 正如其字面所透露的資訊, VBS(VBScript的進一步簡寫)是基於Visual Basic的指令碼語言. 我進一步解釋一下, Microsoft Visual Basic是微軟公司出品的一套視覺化程式設計工具, 語法基於Basic. 指令碼語言, 就是不編譯成二進位制檔案, 直接由宿主(host)解釋原始碼並執行, 簡單點說就是你寫的程式不需要編譯成.exe, 而是直接給使用者傳送.vbs的源程式, 使用者就能執行了.

  我知道菜鳥現在最關心的就是用什麼工具來開發VBS程式了, 答案是:記事本(Notepad).我不是開玩笑, 其實任何一種文字編輯器都可以用來開發VBS開發, 只不過記事本是由系統自帶的, 比較好找而已. 儘管如此, 我還是建議你去下載一個專業的文字編輯器, 因為這些工具可以提供 "語法高亮"等功能, 更加方便開發, 用哪一個隨你喜好, 我比較喜歡Edit Plus (2.10).

  OK, 我們先來寫一個VBScript程式熱熱身.

REM 輸入並回顯你的名字
'使用InputBox和Msgbox函式
Dim name,msg
msg="請輸入你的名字:"
name=Inputbox(msg,"名稱")
Msgbox(name)

  把上面的程式清單輸入到記事本里面, 然後儲存為以.vbs為副檔名的檔案("儲存型別"裡面選擇"所有檔案").然後雙擊執行, 觀察執行結果. 注意:請自己輸入程式清單, 不要複製->貼上!

  我來解釋一下這個程式, 第一行和第二行的開頭分別是"REM"語句和" ' ", 這兩個東西的作用是相同的, 表示本行是註釋行, 就是說這兩行什麼也不幹,只是用來說明這段程式的功能, 版權資訊等等. 註釋行是程式最重要的部分之一, 儘管它不是必需的, 但對於其他人閱讀原始碼, 以及自己分析原始碼是很有好處的. 好的習慣是在必要的地方加上清晰, 簡潔的註釋.

  Dim用來宣告一個變數, 在VBS中, 變數型別並不是那麼重要, 就是說VBS會幫你自動識別變數型別, 而且變數在使用前不一定要先宣告, 程式會動態分配變數空間. 在VBS中你不用考慮name儲存的是一個整數還是一個小數(學名叫"浮點數"), 也不用考慮是不是字串(一串字元, 比如:"Hello World"), VBS會自動幫你搞定. 所以第三行語句可以刪除, 效果不會變, 但我強烈反對這麼做, 一個變數的基本原則就是:先宣告,後使用.變數名用字母開頭,可以使用下劃線,數字, 但不能使用vbs已經定義的字, 比如dim, 也不能是純數字.

  下一行被稱之為"賦值", "="是賦值符號, 並不是數學中的等於號, 儘管看起來一樣.這是正統的理解, 你要理解成等於也沒有什麼不可. 賦值號的左邊是一個變數, 右邊是要賦給變數的值, 經過賦值以後, msg這個變數在程式中等同於"請輸入你的名字:"這個字串,但當msg被再次複製的時候, 原值就會消失. 不光字串, 其他任何變數都這樣被賦值, 例如: a=2, b=12.222等等.

  再往下,Inputbox和Msgbox是VBS內建的函式, 一個函式就相當於一個"黑箱", 有輸入(引數)和輸出(返回值), 你可以不用瞭解函式是怎麼運作的, 只要瞭解這個函式能幹什麼就行了, 我們也可以定義自己的函式, 不過那要等到以後再講. 現在我們只要瞭解, 一個函式可以有返回值也可以沒有, 可以有引數也可以沒有. 例如Inputbox就是有返回值的函式, 我們用賦值號左邊的變數來"接"住InputBox的返回值--就是你輸入的內容. 在inputbox右邊的括號裡是引數列表, 每個引數用","分隔開, 每個引數有不同的功效, 比如第一個引數會顯示在提示裡, 我們把msg這個變數作為第一個引數傳給了Inputbox 函式, 而msg="請輸入你的名字:", 所以我們在對話方塊的提示欄就會看到"請輸入你的名字:" 第二個引數是對話方塊的標題, 我們用直接量(學名叫"常量", 這裡是"字串常量")傳遞給函式, 當然你也可以傳遞變數. Inputbox還有很多引數, 比如你在"名稱"後面再加一個","然後輸入隨便一串字元(字串,用雙引號""包裹起來的一串字元叫做字串)然後執行, 看看結果. 你會發現用於輸入的文字框有了預設的值, 這就是第三個引數的作用.

  Msgbox函式是用來輸出的函式, 在VBS中沒有專門的輸出函式(BASIC中的print,C中的printf), 所以我們只能用對話方塊來觀察輸出結果, Msgbox的必要引數只有一個, 就是要輸出的內容, 在這種情況下, 我們不需要理會msgbox的返回值. 關於Msgbox和Inputbox我們以後還會在討論, 今天只是熱熱身, 到此為止.


要點:

1) 註釋(以REM或'開頭)行在程式中不起作用, 但能讓別人更容易讀懂你的程式.

2) 變數好像一個盒子, 或一個代號, 可以代表你想代表的東西. 變數賦值使用"="

3) 以""包裹起來的字元稱之為"字串"

4) 函式像一個"黑箱", 有引數和返回值, 用"="左邊的變數可以接住返回值

5) Inputbox函式彈出一個輸入對話方塊,Msgbox則用於輸出


作業:

1) 試驗Inputbox的第三個引數

2) 寫一段程式輸出你的年齡

3) 寫一段程式進行3次輸入, 分別輸入你和你父母的姓名(要求顯示提示), 並分3次輸出

第二篇:

我真沒想到, 第一次的作業竟然有人不會.

  看來要講的非常非常細緻才行, 嗯, 今天講各種"量"和基本運算

  先說常量, 這個比較簡單.

  什麼是常量呢, 常量就是其值不可變化的量.

  常量分為兩種:第一種, 自然常量. 這叫是因為它們本身就是常量, 你怎麼更改21的值呢? 他永遠都是21, 不可能變成46

如果你在程式中使用"21=46", 這樣的語句將會引發一個錯誤. 同樣的, 字串也是常量 (還記得字串嗎? 就是包裹在""之間的一串字元), "Hello World"就是一個例子, 如果你使用"Hello World"="Bye"這樣的語句同樣會引發一個錯誤. 你能舉出自然常量的更多例子嗎?

  第二種, 是我們自己定義的常量,這種量也使用代號, 他們也被賦值, 但和變數的不同點在於, 他們在定義的時候被賦值,以後就不能改變了,如果企圖改變將會引發一個錯誤. 定義一個變數,我們使用"const"這個關鍵字(關鍵字的意思是系統定義了有特殊功能的字, 不能作為變數名或常量名使用),格式是:const 常量名=常量值.

例如:

const PI=3.1415926

const NAME="記憶碎片"

  這樣我們就定義了兩個常量, PI和NAME, 一般說來, 常量名全部使用大寫, 但也可以不用, 隨你喜好. 將一些在程式中不需要改變的值定義為常量是個好習慣, 這樣能防止不必要的意外. 另外, 使用自定義常量也可以減少你的工作量. 比如:

msgbox("Hello World")
msgbox("Hello World")
msgbox("Hello World")
msgbox("Hello World")
msgbox("Hello World")

  這個程式輸出五次Hello World, 如果你想要改變輸出為Bye-Bye, 就必須修改全部程式, 當然你可以手動修改5次, 但如果你要輸出1000次呢? 常量就可以替我們解決這個問題:

const hw="Hello World"
msgbox(hw)
msgbox(hw)
msgbox(hw)
msgbox(hw)
msgbox(hw)

  這樣當你要修改輸出的時候只要修改hw的值就行了.

  好了, 現在我們來看看程式設計的第一塊重要"基石":變數. 解釋變數最好的辦法我覺得是"盒子", 一個變數好像一個盒子, 裡面只能裝一個東西, 當你要裝進去別的東西的時候必須把原有的東西拿出來. 這個"盒子"是有名稱的, 當你在程式中使用變數的時候, 系統會開啟盒子取出裡面的東西, 讓這些東西參與處理, 而不是盒子. 有些語言是很依賴"盒子"裡面裝些什麼東西, 這樣才能找到合適的"盒子"(比如C語言), 但VBS給我提供的是能夠自動伸縮的"魔術盒", 我們不用關心裝進去的是什麼東西,

VBS會自動調整盒子的大小. 例如:

Dim a1,a2,a3
a1=14
a2=12.23
a3="Hello"

而不用像C語言那樣麻煩: 或者是VB的正規宣告(VB可以宣告也可以不用)那樣:

int a1; Dim a1 as integer
float a2; Dim a2 as Double
char* a3; Dim a3 as strnig
a1=14; a1=14
a2=12.23; a2=12.23
a3="Hello"; a3="Hello"

嗯……扯遠了……

  變數有什麼用呢? 哇, 那用處可大了. 最簡單, 你並不能確定程式執行時變數的值, 比如前一節課我們編的輸入姓名的程式, 你不能確定InputBox返回的是什麼(還記得Inputbox的返回值嗎? 就是你輸入的內容), 所以你就沒有辦法應對各種情況, 但我們用name這個"盒子"把使用者的名字裝起來, 到用的時候我們只要知道name這個盒子的名字就行了, 系統會自己開啟他並把裡面的內容拿出來用. 再舉個例子, 我們編寫一個程式計算一個矩形的面積, 比如這個程式要發給小學生使用:

dim a,b,s
a=15
b=12
s=a*b
msgbox(s)

  這樣就可以求出長為15,寬為12的矩形的面積了, 是不是很簡單? 當然, 這個程式也可以這樣寫:

dim s
s=15*12
msgbox(s)

  這樣看起來程式短了許多, 也節約記憶體, 但並不是鼓勵的做法, 為什麼? 請看下面.

  現在, 我們的程式要變得像點樣子才行, 誰的程式寫出來還要別人修改原始碼才能用啊?

  所以, 我們要接受使用者的輸入, 還記得嗎? InputBox函式.

  修改後程式如下:

dim a,b,s
a=inputbox("請輸入矩形的長:")
b=inputbox("請輸入矩形的寬:")
s=a*b
msgbox(s)

  ok, 這麼一修改, 無論使用者輸入怎樣的資料, 我們都能計算出矩形的面積了. 如果你用s=15*12能改嘛? 當然不行.

  我想你已經發現了, vbs中的數學計算和真正的算術沒有什麼不同, +,-,*,/,(),[],{}都是一樣的用法, 比如:

dim ans
ans=12+32/4+[(23-10)*2]
msgbox(ans)

  四則運算的法則在程式設計中同樣生效, 你可以在程式設計中重新獲得小學時候的樂趣(你恨數學?那就別學電腦了).

  在程式設計中有一個有趣的運算子是"mod", 這個運算子叫做"取餘運算子", 就是取得一次除法的餘數, 例如

dim a
a=16 mod 5

  你知道a等於幾嗎? Bingo! 沒錯, 就是1. 因為16 / 5 =3....1, 所以mod計算的結果就是1.

  還有一個運算子是"^"(就是鍵盤"6"上面的小箭頭), 他表示"乘冪"(或者是"方") 比如:

dim a,b,c
a=2
b=a^2
c=a^3
msgbox(a)
msgbox(c)

  則b=a*a=4, c=a*a*a=8

  我們一次不要講太多, 這次就講到這裡, 現在總結一下.

要點:

1) 常量分為自然常量和自定義常量, 常量的值不可修改

2) 變數就像盒子, 我們不在乎盒子裡裝的是什麼, 但一定要知道盒子的名字

3) 四則運算在程式設計中沒有任何不同

4) MOD是取餘運算


作業:

1) 編一個程式, 計算圓形的面積, 半徑由使用者給出 (使用Inputbox) PI取值3.14159

2) 編一個程式取得20 / 3 的餘數

第三篇(共六篇):



首先, 我來解決一下上次課程的幾個疑問

第一, 那個餘數問題, 16 / 5 = 3...1, 是因為我改過前面的部分, 後面的忘了改了, 不好意思.

第二, 請看一下程式清單:

1)
Dim a,b,c
a=inputbox("a是:","輸入半徑")
b=Inputbox("b是:","輸入半徑")
c=a*2+b*2
Msgbox(c)
這個 輸入1、2時是6

2)
Dim a,b,c
a=inputbox("a是:","輸入半徑")
b=Inputbox("b是:","輸入半徑")
c=(a+b)*2
Msgbox(c)
這個輸入1、2時是24

  為什麼會不一樣呢? 在數學上c=(a+b)*2 和 c=a*2+b*2是等價的, 在VBS中也是如此. 問題出在"+"上, 在VBS中, +不僅僅是加號的意思還表示把兩個字串連線起來, 例如"Hello"+"World"="HelloWorld" have you understood? 你還記得InoutBox函式的返回值嗎? 是字串! 這就看出問題了吧, 在程式設計中"1"不等於(<>)1, "1"是一個字元, 而1是一個數, 所以a,b都是字串變數, "1"+"2"="12", 這就好像我們小時跟夥伴開玩笑問他們1+1=?一樣, 我們總是笑著說"錯啦,應該是11".但為什麼, a可以*2卻不發生錯誤呢? 這時VBS比較智慧的一個表現, 如果這個字串的內容是一個數且對他進行數學運算, 則把字串強制轉換成數參與運算, 如果字串代表一個數, 但不參加數學運算, 而是參加字串運算(合併)則當作字串處理, 所以你看到a+b=12, 這時候a+b的結果(12)是一個字串, 當它要乘以2的時候就被強制轉換成了數字12, 這樣我就得到了結果24.

  怎麼修改這個程式呢? 我們需要用到另一個內建的函式:int, int函式的功能是將輸入值轉化成整數值, 我們這樣修改:

c=(int(a)+int(b))*2

  這個意思就是把a作為引數傳遞給int函式, int函式就會返回那個整數(你的輸入值), 然後讓返回值參與運算, 這樣就得到了正確答案.所以,以後如果你用的是inputbox函式的話,最好用int語句加工一下:比如c=int(c) 'c是你自己的變數

  大家是不是覺得這個課程有點枯燥, 呵呵, 變數和運算子部分的確是這樣的, 不過多多練習也就好了, 這次, 我們寫寫真正好玩的東西: 流程控制語句. 這個部分開始才是真正的程式設計.

  首先介紹判斷結構.

  在此之前, 我們先介紹一種簡單的變數型別:布林值(Boolean), 這種變數只有兩個可能值:True,Flase,即真或假. 這種變數在某些情況下很有用(比如"開關"). 我們定義一個bool變數的方法和其他變數一樣, 賦值也一樣, 例如:

dim a,b
a=true
b=false

  注意,true和"true"是不一樣的, "true"是字串,true是布林值, 千萬不能混淆.

  回到if語句上來, 我們先來看看簡化版的if語句:if 判斷式 then 語句體 我們來看一個例子:

dim a,b
a=12
b=13
if b>a then msgbox("B大於A")

  我們只看最後一行, a>b這個式子(表示式)有一個返回值, 是bool型的. 因為這個式子只有兩種可能:b大於a, b不大於a, 所以這個式子也只有兩種可能性, 即真或者假. if語句判斷這個表示式的返回值是真還是假, 如果是真(true)則執行then後面的語句, 如果是假, 則不執行, 你把a的值改成14看看還會不會彈出對話方塊?

  當我們要在判斷之後執行多行語句怎麼辦呢, 我們需要用語句塊來解決, 在這裡可以叫塊if

dim a,b
a=12
b=13
if a msgbox("A小於B")
msgbox("B大於A")
end if

  兩個msgbox函式夾在if和end if之間, 這個部分就是語句塊, 塊裡的每一條語句之前請空出4--8(一個鍵)個格, 這不是必需的, 但是是一個好習慣, 以便看清楚程式的結構. 這樣我們就能執行多於一個的語句, 請注意if...then...end if 這三個關鍵部分不要掉了. OK, 我出一個題, 輸入一個數, 如果小於100就輸出"錯誤", 如果大於100就輸出"正確", 我這裡有兩個程式版本:

dim a
a=inputbox("請輸入一個大於100的數")
a=int(a) 'inputbox返回的是字串, 我們把他變成整數 : )
if a>100 then msgbox("正確")
if a<100 then msgbox("錯誤")

還有一個更簡單的

dim a
a=inputbox("請輸入一個大於100的數")
a=int(a) 'inputbox返回的是字串, 我們把他變成整數
if a>100 then
msgbox("正確")
else
msgbox("錯誤")
end if

  看到多了一個else了吧, else的作用就是當要判斷的表示式為false時執行的. 這樣程式就可以處理兩種不同的情況了. 不要忘了用end if結尾

  嘿嘿, 我是變態者, 現在我要你處理三種情況, <100,=100,>100, 還要寫在一個if結構裡, 你怎麼辦, 我給你答案:

dim a
a=inputbox("請輸入一個大於100的數")
a=int(a) 'inputbox返回的是字串, 我們把他變成整數
if a>100 then
msgbox("正確")
elseif a=100 then
msgbox("老大, 你耍我?")
else
msgbox("錯誤")
end if

  這次輸入100看看, 是什麼? else if語句可以在if結構中多次出現, 以靈活判斷不同的情況 (如果你要判斷得太多, 就請使用"選擇結構", 過會兒就講), 當所有elseif都處理完了,而沒有符合情況的時候再執行else中的語句.另一個例子:

Dim a,b,c,d
a=inputbox("a是:","輸入半徑")
b=Inputbox("b是:","輸入半徑")
d=Inputbox("答案:","輸入答案")

c=a*2+b*2 '這裡沒有問題, 會自動轉換
if d=c then
Msgbox("你好聰明")
else
Msgbox("你好豬頭 自己的題還不會!")
end if

  再看看這個, 無論你回答得多麼正確你都是豬頭, 哈哈, 不是我耍你, 還是文章開始時候的inputbox的返回型別在耍你, d是inputbox的返回值, 他是一個字串, 而c是一次整數計算的結果, 他是一個整數. 一個字串無論如何也不等於一個整數, 儘管他們字面上是一樣的:"8"<>(不等於號)8 所以if的判斷式的值永遠是false, 總是執行else部分的語句. 我們可以這麼修改

Dim a,b,c,d
a=inputbox("a是:","輸入半徑")
b=Inputbox("b是:","輸入半徑")
d=Inputbox("答案:","輸入答案")
d=int(d)
'在這裡我們取出了d的值, 變成整數, 在放回"d"這個盒子裡
c=a*2+b*2
if d=c then
Msgbox("你好聰明")
else
Msgbox("你好豬頭 自己的題還不會!")
end if

  這樣就成功了. 這也是Inputbox函式的一個討厭的地方, 沒辦法, vbs沒有其他好的輸入方式了.

  說到if, 我們不得不說一說邏輯運算子, 今天介紹兩種, "and" 和 "or" 學會了if語句之後, 我舉一個例子, 你一看就明白了.

dim a,b
a=inputbox("輸入一個數 >10")
b=inputbox("輸入另一個數 >10")
a=int(a)
b=int(b)
if a>10 and b>10 then
msgbox("正確")
else
msgbox("錯誤")
end if

  這段程式讓你輸入兩個值, 必須都大於10, 只要有一個不大於, 就輸出錯誤

dim a,b
a=inputbox("輸入一個數 >10")
b=inputbox("輸入另一個數 >10")
a=int(a)
b=int(b)
if a>10 or b>10 then
msgbox("正確")
else
msgbox("錯誤")
end if


  這段程式讓你輸入兩個值, 只要有一個大於10, 就返回成功. 其實and和or很好理解, 我讀"if a>10 or b>10 then" 這一句, 用華語是這樣:"如果a大於10或者b大於10, 那麼...". 這樣是不是就很好理解了呢.

  OK, 我們再來看一種新結構, 今天的課就結束, 已經午夜了, 我都累死了.

  當你的程式要處理很多種不同的判斷情況的時候elseif..then會讓程式看起來很雜亂, 所以就有了一種select case結構專門對付這種情況, select case的語法結構很簡單:

select case 變數名
case 值
語句
case 值
語句
case else
語句
end select


  我們舉個例子就能很簡單的說明:

dim a
a=inputbox("輸入一個1--3的值")
a=int(a) '處理inputbox返回字串的問題
select case a
case 1
msgbox("壹")
case 2
msgbox("貳")
case 3
msgbox("叄")
case else
msgbox("輸入錯誤")
end select

  這個例子把1,2,3這三個阿拉伯數字轉化成中國大寫數字, 這個程式寫成if...elseif 的形式如下

dim a
a=inputbox("請輸入1--3的值")
a=int(a)
if a=1 then
msgbox("壹")
elseif a=2 then
msgbox("貳")
elseif a=3 then
msgbox("叄")
else
msgbox("輸入錯誤")
end if

  怎麼樣, 麻煩吧, 還是select好吧.

  OK, 今天到此結束, 總結一下:


要點:

1) inputbox返回的是一個字串, 而不是一個數, 必須用a=int(a)這種形式轉化成數

2) bool變數的值只有兩種:true,false

2.5) and兩邊的表示式都是true, 則返回true. or兩邊的表示式有一個是true, 就返回true

3) if 語句的格式

4) select...case的格式


作業:

1) 使用3個bool值, 儲存你的3兄弟姐妹是否是男性 (提示:sister1male=false)

2) 給定一個個數, 大於10而且小於20輸出"正確", 否則輸出"錯誤"

3) 輸入12,或者15, 輸出"正確", 否則輸出"錯誤"

4) 把5以內的正整數都轉換成中國大些數字

5) 自己隨便設計一個程式, 應用今天的知識

四篇(共六篇):



大家好, 昨天我休息了一天, 所以今天寫第4章:迴圈結構

  我們先來看一道題:商場進行每日結算, 要求累加出今天的營業額, 每次輸入一個數, 這道題其實很簡單, 但就我們現在學

過的知識要完成這道題相當麻煩, 我們來分析一下. 首先, 我們需要知道買賣的次數, 這樣才能控制輸入的次數,但是, 這種設

計是非常低效的, 每天都要重新設計程式. 假定今天進行了5次交易, 以下是源程式:

dim sum
sum=0 '初始化變數
sum=sum + int(inputbox("請輸入交易額"))
'sum=sum+x 這種形式是把本身的值取出來, 進行一次運算, 再放回本身, 這種方法很有用處
'這裡使用了函式巢狀, 把inputbox的返回值直接傳給int函式, 轉化成整數, 下同
sum=sum + int(inputbox("請輸入交易額"))
sum=sum + int(inputbox("請輸入交易額"))
sum=sum + int(inputbox("請輸入交易額"))
sum=sum + int(inputbox("請輸入交易額"))
msgbox(sum)

  看到了嗎, 我透過把計算過程複製了5遍才設計好了程式, 這種程式在汽車交易所等交易次數少的地方還能湊合著用, 如果

放到超市豈不是要複製, 貼上幾千遍? 我們今天講的內容就可以克服這種缺陷, 首先, 我們來講以下Do...Loop語句.

  do...loop的結構看上去非常簡單, 就是:do...loop, 僅此而已, 這個結構不斷執行do和loop之間的語句(學名叫:迴圈體),
永不停止. 舉個例子來說:

do
msgbox("這個資訊會不斷重複出現, 要停止程式請使用工作管理員(Ctrl+Alt+Del)中止wscript程式")
loop

  執行這個程式, 當你點銷掉一個對話方塊馬上會出來另一個, 你永遠點不完, 總有下一個. 誰會執行這樣的程式? 除非是給

別人搗亂(我就幹過這種事), 所以在do..loop結構中還有一個語句:exit do, 這個語句將終止迴圈, 跳到loop後面的語句繼續

執行. 據個例子來說:

dim a '注意:常量不需要在dim裡面宣告,否則會引發錯誤
const pass="123456" '這是一個字串 請用""包裹起來. 設定密碼為常量, 不可變更
do
a=inputbox("請輸入密碼")
if a=pass then
msgbox("密碼校驗成功")
exit do
end if
loop

  這個程式會一直不停的問你密碼, 知道你輸入了正確的密碼為止.(if可以巢狀在另一個if當中, 也可以巢狀在迴圈體當中

, 所以一定要用縮排, 來分清楚程式的各個部分). 這個程式是很經典的, 早期的程式都是這麼做的. 但是我們是Hacker, 所以

我們瞭解系統的安全性, 這種無限次認證程式很容易被窮舉破解, 我們要來限定認證的次數. 修改程式如下

dim a,ctr
ctr=0 '設定計數器
const pass="pas123_" '上面的那個是弱密碼, 這次改的強一點
do
if ctr=3 then
msgbox("已經達到認證上限, 認證程式關閉")
exit do
else
a=inputbox("請輸入密碼")
if a=pass then
msgbox("認證成功")
msgbox("(你可以在這裡加一段成功後得到的資訊)")
exit do
else
ctr=ctr+1 '如果密碼出錯就增加一次錯誤認證計數
msgbox("認證出錯, 請檢查密碼")
end if
end if
loop

  執行這個程式試試看, 當你出了3此錯誤以後, 就會停止再次詢問密碼, 關閉程式. telnet認證用來限制次數的程式與此大

同小異. 要注意的是巢狀的if語句, 清仔細讀一下這個程式, 可能比較難懂, 也請你試著自己設計一下類似的程式.

  其實, 要在do...loop加上驗證的功能, 並不一定要用if, 我們可以直接利用do. 我來介紹一下while關鍵字, while可以放
在do或者是loop後面, 然後再接一個表示式, 當表示式的值為true的時候(表示式成立),才執行迴圈體.我們來看一下修改後的
程式"

dim a,ctr
ctr=0
const pass="pas123_"
do while ctr<3
a=inputbox("請輸入密碼")
if a=pass then
msgbox("認證成功")
msgbox("(你可以在這裡加一段成功後得到的資訊)")
exit do
else
ctr=ctr+1 '如果密碼出錯就增加一次錯誤認證計數
msgbox("認證出錯, 請檢查密碼")
end if
loop

  這樣實現的功能和上一個例子完全一樣, 我們再來看看把while放在loop後面:

dim a,ctr
ctr=0
const pass="pas123_"
do
a=inputbox("請輸入密碼")
if a=pass then
msgbox("認證成功")
msgbox("(你可以在這裡加一段成功後得到的資訊)")
exit do
else
ctr=ctr+1 '如果密碼出錯就增加一次錯誤認證計數
msgbox("認證出錯, 請檢查密碼")
end if
loop while ctr<3

  功能是一樣的, 為什麼要放在loop後面呢? 你把ctr的值改成3就知道了, while在do後面的程式會直接退出, 而在loop後面

還會允許一次認證, 到了loop才結束.和while相反的是until, 用法和while一樣, 不過他只有當後面的表示式的值為false(表

達式不成立)的時候才執行迴圈體, 請自己試驗一下

  ok, 我們來看另外一種迴圈結構,for....next, 這種迴圈結構是基於計數的, 也是在程式設計中最常見到的迴圈結構.

dim i
for i=0 to 5
msgbox(i)
next

  看到了嗎?每次輸出的i都是遞增的, 但我們沒有明確指出i要遞增, 當i達到5的時候, 迴圈就結束了, 因為由0開始, 所以

迴圈體執行了6次, 這一點很重要, 大部分東西都是從0開始而不是1. 這個程式也可以寫成

do的形式:

dim i
i=0
do while i<5
msgbox(i)
i=i+1 '因為do不能自動計數, 必須手動加
loop

  怎麼樣, 還是for比較好用吧. for在程式設計中很有用途, 我們再舉一個例子, 順便講一下巢狀迴圈.

dim i,j
for i=1 to 9
for i=1 to 9
str=str & i * j & " " '&是和並字串的符號
next '每個next對應一個for
next

  看看執行結果, 是否令你會想起小學時代的數學老師(醜陋的嘴臉). 要注意, 這裡有一個"大"的for, 和一個小的for, 當

小的for執行完一個週期以後, 大的for才執行一次(換句話說, 大的for執行一次, 小的要執行9次), 所以一共執行了九九八十

一次. 在大的for裡可以不僅僅是一個小的for, 也可以加上另外的語句. 我們來修改一下源程式:

dim i,j
for i=1 to 9
for i=1 to 9
str=str & i * j & " "
next '每個next對應一個for
str=str & vbCrlf 'vbCrlf相當於鍵盤上的Enter鍵,因為你不能在鍵盤上輸入,所以系統定義了一個預設的常量
next

  這次執行完成以後, 輸出結果按照乘數進行了分割, 每小for執行完一次, 就換一行(透過vbcrlf).

  這次的內容對菜鳥可能比較難懂, 掌握的辦法只有一個:多實踐. 另外, 我在論壇看到很多人還是問:"VBScript要用什麼工

具編?"我就很氣憤, 我在第一篇裡面已經說明:用記事本編輯原始碼, 然後儲存為以.vbs為副檔名的程式就可以了, 請大家不要

再問. 另外, 國產的一種垃圾軟體"超級X霸"搶佔了vbs這個副檔名, 請把那個垃圾解除安裝掉.

  我們總結一下:

要點:

1) do..loop和exit do的用法

2) while當表示式true的時候執行迴圈體,until反之

3) for...next是計數迴圈, 每次執行計數器遞加

4) 巢狀迴圈的作用和寫法

4.5) &用於連線字串

5) vbCrLf相當於鍵盤上的Enter鍵


作業:

1) 在我國的數學經典著作"九章算術"中有這樣一道題:百錢買百雞, 公雞5錢一隻, 母雞3錢一隻, 小雞1錢2只(這個資料我是參

考一本程式設計書的, 但我記得是公3,母1,小1錢3只? 不管了, 就按照書上得來吧)求得是能有多少種辦法買這些雞. 如果看不懂的

話我用大白話說說:有人要去買雞, 用100塊錢正好買了100只雞, 價格如下:公:5$, 母:3$, 小:1$ for 2, 讓你求一共多少種賣

法(公母小怎麼搭配). 請用迴圈解決這個問題.

ps:今天要去移民局辦事, 所以文章寫的很倉促. 大部分程式碼都沒有實驗, 請大家幫我找錯. 另外, 上次的作業大家在論壇應該

看到了, 我就不重複答案了, 不知道大家喜歡做這種題, 還是以前那種比較簡單的?


第五篇(共六篇):

請允許我縣描述一下我現在的環境:氣溫高達37攝氏度, 而我忘記了圖書館開門的時間, 還要在這裡站上一個小時, 在熱帶植物的包裹下, 各種奇怪的小飛蟲圍著我轉來轉去. 不過令我欣慰的是, 終於寫到五了, 還有兩課我們的"基礎篇"就要結束了.

今天我們來了解語言本身的最後一個論題:陣列.

  要理解"陣列", 這個概念我覺得另一種翻譯對學習來說更加容易:"陣列", 沒錯, 陣列就是一個陣列, 一個資料的陣列. 最簡單的例子是資料庫系統, 假設你要儲存20名學生的英語成績, 如果不是用陣列, 你則要建立20個不同的變數, 累死. 陣列就是型別相同(重要!)的一組資料(或者n組), 用來儲存相關的量, 最簡單的陣列是一維陣列, 我們就先來學習它吧.

  什麼是一維陣列呢? 在3維以下,你可以利用幾何知識來理解"維"的概念,一維相當於一條線, 二維則是一個矩形, 三維是一個長方體. 我知道這麼講是很抽象的, 我們先舉個一維陣列的例子就比較容易瞭解了.

dim a(9) '從零開始
for i=0 to 9
a(i)=i '填充每一個陣列元素
msgbox(a(i)) '輸出陣列元素
next

  我們可以看到, 定義一個陣列的方法和定義一個變數沒有什麼不同, 同樣是使用dim語句. 定義一維陣列的方法如下:

dim 陣列名(元素數量), 這裡大家要注意一點, 這裡定義的元素數量總是比你要的要少一個, 因為一個陣列的起點是0號資料而不是1, 所以大家一定要小心: 你需要10個資料, 就定義"9", 需要100個就定義99, 依此類推. 陣列的元素可以看成一個個獨立的變數, 你可以像獨立的變數那樣使用他們. 陣列元素的量可能是毫無關係的, 比如第一個陣列元素儲存你的年齡, 第二個儲存今年西瓜的銷售量, 但這種做法是不鼓勵的, 甚至是不被接受的, 不要這麼幹, 這樣的情況請定義獨立的變數. for語句在陣列中可算是大顯身手, 還記得for嗎? 它累加一個變數, 我們可以把這個變數應用在陣列中正好用來讀取或者填充按照順序排列的陣列元素, 上面就是這樣一個例子. 陣列其實是很簡單的東西(再BASIC語言裡面), 陣列難的是怎麼搗弄這些迴圈, 讓他們按照你的要求運轉. 這個等到二維陣列再說, 我們先看看如何手工填充陣列.

  如果你這個都想不到的話, 那你真是白學了:

dim name(7),str '一共八個學生, str變數是用來把他們儲存成一個字串以便輸出
for i=0 to 7
name(i)=inputbox("請輸入第" & i+1 & "個學生的名字")
str=str & " " & name(i)
next
msgbox(str)

  這樣我們就有了一個小小的資料庫, 它們的資料排列可以看成這樣:

  name(0),name(1),name(2).....name(7)

  看到了吧, 所以我說我們可以把它看成是"一條線", 等到我們學到了檔案操作, 就可以把他們輸出到檔案中去了. 一維陣列有很多用處, 我們來看一下一個複雜的例子. 我們要儲存3各學生的名字, 身高, 成績這三種資料, 由於名字是字串, 而身高可能是浮點數(帶小數點的數), 成績則可能是整數, 所以我們不能把他們儲存在一個陣列裡面(不要忘記, 陣列織只能儲存同類的資料), 所以我們要建3個陣列, 以下是例程:

dim name(2), high(2), mark(2) '定義三個陣列分別儲存3個人的名字, 身高和得分
dim ctr '計數器
for ctr=0 to 2
name(ctr)=inputbox("請輸入第" & ctr+1 & "個學生的姓名")
high(ctr)=inputbox("請輸入第" & ctr+1 & "個學生的身高")
mark(ctr)=inputbox("請輸入第" & ctr+1 & "個學生的得分")
next

  OK, 我們已經填充好了資料, 現在我們的小小資料庫只能按順序輸入, 我們要讓它看起來像點樣子, 我們來給他設計查詢功能:

'接著上面的程式
dim cname, temp '要查詢的名字, 和一個臨時變數, 用來儲存資料的位置
cname=inputbox("請輸入你要查詢的名字:")
for ctr=0 to 2 '遍歷所有name陣列的成員, 尋找要查詢的名字
if name(ctr)=cname then
temp=ctr '記錄資料位置
exit for '退出迴圈, 和exit do的用法一樣
end if '不要忘了end if
next
msgbox("姓名:" & name(temp) & " " & "身高:" & high(temp) & " " & "得分:" & mark(temp))

  嘿嘿, 有意思吧, 其實在這個程式裡面, 那個temp變數完全沒有必要, 只是為了更清楚地說明問題. 因為當exit for以後ctr變數的值就不會改變, 儲存的正好是對應資料在陣列中的位置, 寫這個temp變數是為了照顧到以後要學C++的朋友(C++可以在for語句裡宣告新變數, 只在這個for結構中有效, 所以到了外部就不能訪問了). 也就是說可以簡化成如下:

dim cname
cname=inputbox("請輸入你要查詢的名字:")
for ctr=0 to 2
if name(ctr)=cname then exit for '因為只有exit for就不需要塊if了
next
msgbox("姓名:" & name(ctr) & " " & "身高:" & high(ctr) & " " & "得分:" & mark(ctr))

  這是最直接的路子. 好好重讀一下上面所有的原始碼, 然後自己寫幾個程式, 完全搞清楚一維陣列及其應用以後再看後面的二位陣列. 二維陣列好像是一個一維陣列的集合, 就好像"線積成面"一樣, 由n各一維陣列組成二維陣列, 這是初學者比較好理解的辦法(比較精確的是用"編號"的概念去理解, 因為4維以上的陣列就比較難以用歐幾里德幾何概念去解釋了). 二維陣列是很好解釋的, 我們來看一下:

dim a(2,2) '從零開始, 一共有3 X 3 = 9 個資料
dim i,j '需要兩個計數器
for i=0 to 2
for j=0 to 2 '使用巢狀迴圈
a(i,j)="X"
next
next

  我們建立了一個這樣的二維陣列(那些","是我用來分割元素的,並不存在), 瞭解二維陣列的了嗎? 不清楚我們再講一下

編號 0 1 2
0 X,X,X
1 X,X,X
2 X,X,X

  二維陣列的看起來是不是就是一個矩形呢?(你在記憶體中看不到這樣的矩形, 只是便於你理解), 每個資料都有編號, 由兩個數來定位, 這個很像(非常像)你在國際象棋棋盤上尋找一個格, 我們用類似"C6","A2"這樣的"垂直座標"進行定位, 對, "垂直座標", 很確切. 我們要使用一個二維陣列元素的時候可以和普通變數一樣使用, 只要指定陣列元素的"定位點"就可以了, 例如

a(0)(1)=1, b(2)(1)="你好", 諸如此類. 要注意的是二維陣列也只能儲存型別相同的元素, 而且上標(起點)也從0開始. 計算一個二維陣列的元素個數只要把兩個下標+1(以得到實際的值)再乘起來就可以了, 非常類似於求一個矩形的面積.

  假如需要儲存的都是同一型別的資料, 我們就可以用二維陣列, 比如要儲存5個人的姓名,國籍,民族, 就可以使用二維資料

dim info(4,2) '一共五個人, 要儲存的資料型別有3項
dim i,j
for i=0 to 4
for j=0 to 2
dim opt '定義一個變數用於儲存資料項提示
select case j '判斷應該輸入的是什麼資料
case 0
opt="姓名"
case 1
opt="國籍"
case 2
opt="民族"
end select
info(i,j)=inputbox("請輸入第" & i+1 & "個人的" & opt)
next
next
'輸出太麻煩了, 我懶得動, 你知道那麼回事就行了

  這樣就不需要定義3個一維陣列了.

  多位陣列(三維以上)的定義和使用方法與二維陣列一樣, 但不太好在歐幾里德幾何空間裡加以解釋, 幸好我們並不太常用那麼多維的陣列.定義一個三位陣列:dim a(1,2,3) '一共24各陣列元素.

  今天因為要搬家(我喜歡Sengkang啊, 可是MM嫌交通不便, 誰不知道她只想去逛街),而GF要去和她的同學去參加什麼試驗半夜才回家, 所以下午我只能自己去押車搬家了, 5555~~好可憐, 這次就請大家原諒我少寫一點, 我可是站在圖書館外寫的啊,

現在腿都軟了~~~ 本來還要講"動態陣列"的, 但想了想還是放到"進階部分"再說吧.

要點:

1) 一維陣列是"線", 二維陣列是"面", 三維陣列是"體" (多維陣列就亂套)

2) 陣列的下標從0開始

3) for迴圈在陣列的應用中起了很大作用, 二維陣列需要巢狀迴圈

作業:

  上次出的"百雞問題", 大家喜歡嗎? 以後我們就做這種需要動腦的題目, 那些簡單的實踐, 大家一定要多做!

1) 定義一個陣列, 包含5個元素, 都是隨機整數(隨便輸入), 要求把他們按照從大到小的順序排列起來

2) 有兩個二維陣列a(4,4)和b(4,4) (元素值隨便), 交換兩個陣列(原來的a的所有元素值變成b的, b的所有元素值變成a的)


最後一篇:

新家不錯, MM開心, 我也就跟著高興了 : ), 今天我們學習基礎篇的最後一個部分:自定義函式和過程. 我們每天都在和函

數打交道, inputbox()是函式, msgbox()是函式, int()也是函式...這些函式都是系統內建的, 我們只能用不能改. 今天, 我

就教大家怎樣自己製作一個函式.

  首先我們要了解, 為什麼要用函式, 我們用"例項"說話, 先看一個例子: 給出兩個數, 輸出較大的那一個.

dim a1,a2,b1,b2,c1,c2
a1=2:a2=4 '":"可以讓你把多個語句寫在一行上
b1=32:b2=67
c1=12:c2=898

if a1>a2 then
msgbox(a1)
elseif a1 msgbox(a2)
end if

if b1>b2 then
msgbox(b1)
elseif b1 msgbox(b2)
end if

if c1>c2 then
msgbox(c1)
elseif c1 msgbox(c2)
end if

  多麼麻煩呀, 我們把相同的比較過程複製了好幾遍, 早期語言沒有結構化(沒有過程和函式)的時候, 程式設計師們的確是這麼

乾的, 他們複製(Copy), 那個年代也沒有剪貼簿這一說, 大家都是重新輸入程式碼. 後來工作簡化了:


dim a1,a2,b1,b2,c1,c2
a1=2:a2=4
b1=32:b2=67
c1=12:c2=898
msgbox(co(a1,a2))
msgbox(co(b1,b2))
msgbox(co(c1,c2))

function co(t1,t2) '我們使用function定義了一個新的函式
if t1>t2 then
co=t1 '透過"函式名=表示式"這種方法返回結果
elseif t2>t1 then
co=t2
end if
end function

  我們在這裡是用了一個新的關鍵字:funciton, 這個關鍵字表示一個新函式開始, 格式:

funciton 函式名(引數1, 引數2...引數n) '列表可以是空的, 但括號不能省略, 引數之間用","分割
...
exit funciton '結束函式, 不是必需的
...
end function

  函式是一個模組, 只有你呼叫的時候才會執行, 也就說, 當你編寫了一個函式, 然後在程式中並不呼叫它, 那麼這個函式

永遠不會執行. 一般來說, 我們編寫程式是按照:

主程式
..
..
..

函式1
..
..

函式2
..
..

  詳細解釋一下: 函式中最重要的是引數和返回值. 引數是在函式名後面的()裡定義的, 用","分割, 使用引數的時候我們也

用","分割. 說到這裡我想起一件事, 昨天有個朋友給我發訊息問我:

  msgbox(name1,name2,name3)

  這個錯在哪裡? 為什麼不能同時顯示出三個變數? 這就是因為你用了",", 這個符號表示你輸入的三個量作為三個不同引數

傳遞給msgbox()函式, msgbox()函式只會顯示出第一個引數, 第二個引數的作用是出現在標題欄. 所以你應該用"&"或者"+"把

三個字串變數連線起來, 作為第一個引數傳遞給msgbox()函式. 程式設計師說引數的時候經常說到"形參", "實參"這樣的"黑話",

我來解釋一下. "形參"是"形式引數"的簡稱, "實參"是"實際引數"的簡稱, 實參是指你呼叫函式的時候傳遞給函式的量, 可以

使變數或者常量(直接量), 例如:co(12,24)中的12,24就是實參. 形參是你在函式定義時定義的變數, 這些變數用來"接住"傳遞

過來的量, 例如function co(t1,t2)t1,t2就是形參.

  在VBScript中, 引數傳遞是一種傳值, 而不是傳址(聽不明白不要緊, 學了C語言的指標你就明白了), 所以我們進行的參

數傳遞實際上是進行了一次變數賦值, 例如我們呼叫co(a1,a2), 實際上程式會執行一步:t1=a1,t2=a2這樣的操作. 同樣因為傳

值傳址的原因, VBScript只能返回一個值, 我們先來看看什麼叫"返回". 當一個過程呼叫了另一個過程的時候(比如主程式呼叫

了函式), 控制權就到了被呼叫過程那裡, 當這個過程執行完畢以後, 會回到呼叫它的地方繼續執行, 這個就叫做"返回", 返回

的時候可以帶一個值叫做"返回值"(這是"通俗"的理解). 在vbs繼承了basic的傳統, 返回的時候採用"函式名=返回值"的辦法,

這個"返回值"是指一個表示式(在程式設計中, 任何東西都是表示式, 比如變數a, 常數0, "Hello",c=1+2等等這都是表示式). 比如

有一個函式是ht, 則返回的方法是:ht=你要返回的值. 注意:返回以後, 後面的語句將不再執行.

  呼叫一個函式我就不用講了吧:變數=函式名(引數)

  有時候我們並不需要返回什麼值, 這個時候我們可以使用一種稱之為"子程式"的結構. 子程式或稱之為過程與函式的差別

就在於:1) 沒有返回值, 2) 使用sub關鍵字定義, 3) 透過Call呼叫.具個例子:

dim yname
name=inputbox("請輸入你的名字:")
call who(yname)

sub who(cname)
msgbox("你好" & cname)
msgbox("感謝你閱讀我的課程")
msgbox("這是基礎部分的最後一課")
end sub

  你一定看明白了, 很簡單的. 退出一個過程和退出一個函式一樣:exit sub(函式:exit function).

  要注意, 子程式(過程)是比較特殊的一個結構, C等語言是沒有這個概念的, C語言中的一切都是函式, 沒有返回值的函式

在C語言中只要使用void修飾符定義就行了.

  今天沒有什麼可講的了, 基礎篇就這麼結束了, 目前你已經有了基本的程式設計概念(程式導向的結構化程式設計), 可以選擇學習

另外一種語言(比如C或Pascal), 現在的基礎會有一定的幫助. 如果你想要繼續學習vbs或透過它更詳細的瞭解程式設計在轉型可以

跟我繼續學習, 但因為我的假期結束所以更新的時間可能會比較慢, 請大家原諒.初步計劃如下:


進階篇:

變數的深入討論
|
|----變數型別
|
|----變數的有效範圍
|
陣列的深入討論
|
|----動態陣列
|
函式的深入討論
|
|----陣列作為函式引數
|
|----多個返回值
|
字串操作
|
|----亂七八糟一大堆
|
物件導向程式設計(OOP)的基本知識
|
檔案操作
|
|----FSO物件
|
|----其他相關部分
|
VBS與網頁
|
|----HTML中嵌入VBS
|
|----VBS與表單(設計你的程式介面 wow!)


實戰篇:

病毒程式設計

Socket程式設計(TCP/UDP)


  這只是大概的內容, 我想應該會有變化, 到時候你就會讀到的. 今天的內容請多多實踐, 作業就是把前面的各個課程在溫

習一下. 對要離開這個課程去更進一步學習的朋友:祝你再學習程式設計的道路上一帆風順。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-949465/,如需轉載,請註明出處,否則將追究法律責任。

相關文章