嗯, 以最近來說, 我已經很少 post 這麼多字的文章...
這是在 BBS 上討論的, 我是覺得對入門者轉進階者滿有價值的, 所以就又把它轉貼過來!
之前的部分若有興趣, 請自行參閱
http://bbs.openfind.com.tw/cgi-bin/qsearch?QUERY=VB%A9%C7%B2%7B%B6H%A4%A7%A4G&TYPE=ALL&FUZZY=0&DATE=0&EXACT=1&SORTBY=-1&query_userid=&BOARD=&BOARD0=
----------------------------------------------------------
發信人: Devil@bar (璉璉), 信區: programming
標 題: Re: VB怪現象之二
發信站: 成大資工_BBS ( Nov 6 10:26:13 2000)
───────────────────────────────────────
==> cyrex.bbs@bbs.nsysu.edu.tw (我依然是小呆瓜) 在 programming 版提到:
: ==> yonkov.bbs@sun.dyu.edu.tw (莊頭北) 的文章中提到:
: >※ 引述《cyrex.bbs@bbs.nsysu.edu.tw (我依然是小呆瓜)》之銘言:
: >我想這是不正確的
: >dim myarr()表示宣告myarr是動態陣列,可以用redim改變大小
: >若只宣告dim myarr()不單myarr(1)不能用,就連myarr(0)也不能用
: >我想這也不正確
: >見下列程式段
: >Sub main()
: > Dim a()
: > a = Array(1, 2, 3)
: > Debug.Print a(1)
: >End Sub
: >執行結果是2
不好意思... 我來說點... 在 MSDN 中關鍵字為 SafeArray
: Sorry!!我的觀念有點錯誤~~文章要修正
: 當ParamArray 變數()時,這裡的變數是一個陣列
: 而Dim myarr()
這裡其實已經完成一個變數的定址, 型態是 Variant 的子型態, SafeArray
這時, 陣列描述器已定址, 但陣列尚未形成!
: myarr = Array(1,2,3)
Array 傳回的是 Variant 的 SafeArray , 由陣列描述器內之維度, 下標, 個數
(Count) , 及陣列實際位置指標填入 MyArr的陣列描述器內...
這部分我實際觀察過記憶體變化, 起初不明瞭, 待看過 SafeArray 就懂了!
: 時是1,2,3這些資料被擠到myarr單一元素的變數裡(此時myarr還沒有上下限)
: 經過
: Sub MySubrtin(ParamArray Datas())
: ^^^^^^^
ParamArray 的特性是每個元素都是一個 Variant 型態...
自然, 可以將 SafeArray 的型態存入 Variant 內!
: ParamArray的特性會將傳來的數值組成陣列,因此myarr就變成Datas(0)
對於 Datas(0) 來說, 它是與 MyArr 指向同一位置的陣列描述器
: 所以是For Each I In Datas(0)
: Ex:
: Private Sub Command1_Click()
: Dim A()
: Dim B()
: A = Array(0, 1, 2, 3, 4, 5)
: B = Array(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
: Z A, B
: End Sub
: Sub Z(ParamArray C())
: For Each D In C
: For Each E In D
: MsgBox E
: Next
: Next
: End Sub
簡單的說, 標準的 Variant 有 16 Bytes! 若是陣列, 將在第 9 ~ 12 位置產生
一個指標指向陣列描述器 (不定長度字串是指向字串實體位置) , 再由陣列描述
器第 13 ~ 16 位置指向陣列實體位置!
陣列描述器大小為 16 + 維度 * 8
假設
標準的 Variant 有 16 Bytes Addr1
陣列描述器 Addr2
陣列實體 Addr3
分別代表 3個記憶體位置, 則
MyArr, Array的傳回值, Datas(0) 的 Addr1, Addr2 為私有,
Addr3 為公有!
若 ByVal ParamArray
則
Datas(0) 的 Addr3 為動態私有, 不與 MyArr 共用!
當 Array傳回值碰上 End Sub 之類的敘述, 則 Array傳回值的 Addr1, Addr2
將會釋放還給系統! 若碰上下一個 Array ,則將重新配置 Addr1, Addr2
對於這些機制夠了解, 就可以自製類似 Array的函數, 甚至不限維度! 也可以
輕易轉換維度!
培基語言網頁內的陣列工具篇就是這樣寫出來的!
(http://feitsui.hyd.ncku.edu.tw/TLCheng/Basic/index.htm)
補充:
Datas 有自己的 Addr1, Addr2, Addr3!
Datas(0) 的 Addr1 是在 Datas Addr3 的第 1 ~ 16 的位置
另位置基底採用 Basic慣用為 1, 與 C慣用位置基底為 0不同!