none
VB2005的陣列表示方法 RRS feed

  • 問題

  •  

    我突然發現一件事,VB2005的二維陣列表示方法竟然可以和C、Java類似

     

    VB2005

     

    a(i,j)

     

     

    a(i)(j)

     

    編譯都可以過...

     

    我想請問各位高手,這兩種表示方法有差嗎?

    2008年1月22日 下午 02:33

解答

  • 標準陣列:

    a() 使用到三個記憶體位置

    a 為變數記憶體,內含一個參照指標,指向陣列描述器

    陣列描述器為描述陣列實體維度、型別、長度等,內含一個指標指向實體陣列

    a(0) 或 a(0, 0) ,為實體陣列第一個元素,在陣列描述器長度內的一段連續的區塊記憶體均為同一陣列

     

    a(i, j) 為標準陣列,所以資料為連續且為矩形區塊。

     

    a(i)(j) 有 1 + (1+ i) 個標準陣列,即 a, a(0), a(1), ..., a(i) 均為標準陣列,而 j 可不等長。

    a 本身為標準陣列,所以 a(0) ~ a(i) 每個元素均為子陣列的延伸參照,所以 a(0), a(1), ..., a(i) 在記憶體中不連續,若同時宣告配置,則在記憶體節省的情形下,通常為連續配置。

     

    因此在 a(i)(j) 使用上,要經過 6 次記憶體定址,存取上當然比 a(i, j) 3 次記憶體定址慢,但是 a(i)(j) 的彈性相對比 a(i, j) 大。

    2008年1月22日 下午 03:14
    版主
  • 前面說過,a(0), ..., a(i)  都是標準陣列的參照,所以你可以當成實際上是 b, c, d, e, ... 等子陣列。

     

    子陣列的維度如何取得?

    UBound(b), UBound(c), ..

     

    所以就是

    UBound(a(0)), ..., UBound(a(i))

     

    這種陣列並沒有維度限制,所以可以做成樹狀結構,也有人稱為樹狀陣列,亦即各子陣列維度可以不定。

     

    例如:

    Dim a(2) As Object

    ...

    a(0)

    a(1)(4)(2, 3)(4, 2, 1)(3)

    a(2)(5)

     

    a(0) 可以是一個純數值

    a(1) 下面可以有多層陣列,並不限定為一維

    a(2) 下面只有放一層一維陣列

     

    所以取得 a(1) 下面多維陣列的上限:

    UBound(a(1)(4), 2) 取得二維陣列的第二維上標索引值。

    2008年1月23日 上午 05:41
    版主

所有回覆

  • a(i, j) 是多維度型陣列(Multi-dimensional Array)宣告。

    a(i)(j) 是陣列中陣列的宣告法,這種陣列又稱為 Jagged Array。

    2008年1月22日 下午 02:49
    版主
  • 這兩種表示方法在存取上都沒有差別嗎?

     

    效率之類的...

     

    2008年1月22日 下午 02:52
  • 沒測過不知道。

    我自己也已經很少用多維度陣列了,都用 Collection 比較多。

     

    2008年1月22日 下午 02:58
    版主
  • 標準陣列:

    a() 使用到三個記憶體位置

    a 為變數記憶體,內含一個參照指標,指向陣列描述器

    陣列描述器為描述陣列實體維度、型別、長度等,內含一個指標指向實體陣列

    a(0) 或 a(0, 0) ,為實體陣列第一個元素,在陣列描述器長度內的一段連續的區塊記憶體均為同一陣列

     

    a(i, j) 為標準陣列,所以資料為連續且為矩形區塊。

     

    a(i)(j) 有 1 + (1+ i) 個標準陣列,即 a, a(0), a(1), ..., a(i) 均為標準陣列,而 j 可不等長。

    a 本身為標準陣列,所以 a(0) ~ a(i) 每個元素均為子陣列的延伸參照,所以 a(0), a(1), ..., a(i) 在記憶體中不連續,若同時宣告配置,則在記憶體節省的情形下,通常為連續配置。

     

    因此在 a(i)(j) 使用上,要經過 6 次記憶體定址,存取上當然比 a(i, j) 3 次記憶體定址慢,但是 a(i)(j) 的彈性相對比 a(i, j) 大。

    2008年1月22日 下午 03:14
    版主
  •  

    不愧是高手中的高手,超佩服的!
    2008年1月22日 下午 04:28
  •  璉璉 寫信:

    標準陣列:

    a() 使用到三個記憶體位置

    a 為變數記憶體,內含一個參照指標,指向陣列描述器

    陣列描述器為描述陣列實體維度、型別、長度等,內含一個指標指向實體陣列

    a(0) 或 a(0, 0) ,為實體陣列第一個元素,在陣列描述器長度內的一段連續的區塊記憶體均為同一陣列

     

    a(i, j) 為標準陣列,所以資料為連續且為矩形區塊。

     

    a(i)(j) 有 1 + (1+ i) 個標準陣列,即 a, a(0), a(1), ..., a(i) 均為標準陣列,而 j 可不等長。

    a 本身為標準陣列,所以 a(0) ~ a(i) 每個元素均為子陣列的延伸參照,所以 a(0), a(1), ..., a(i) 在記憶體中不連續,若同時宣告配置,則在記憶體節省的情形下,通常為連續配置。

     

    因此在 a(i)(j) 使用上,要經過 6 次記憶體定址,存取上當然比 a(i, j) 3 次記憶體定址慢,但是 a(i)(j) 的彈性相對比 a(i, j) 大。

     

    再請問一下,關於a(i)(j),其 j 可以不等長,那當我在使用Ubound(a,2)時,函數會傳回什麼東西?

    2008年1月22日 下午 05:20
  •  

    自己試過之後發現,會出現「rank引數無效」的錯誤。

     

    請問,我該如何取得 j 的長度?

    2008年1月22日 下午 05:49
  • 前面說過,a(0), ..., a(i)  都是標準陣列的參照,所以你可以當成實際上是 b, c, d, e, ... 等子陣列。

     

    子陣列的維度如何取得?

    UBound(b), UBound(c), ..

     

    所以就是

    UBound(a(0)), ..., UBound(a(i))

     

    這種陣列並沒有維度限制,所以可以做成樹狀結構,也有人稱為樹狀陣列,亦即各子陣列維度可以不定。

     

    例如:

    Dim a(2) As Object

    ...

    a(0)

    a(1)(4)(2, 3)(4, 2, 1)(3)

    a(2)(5)

     

    a(0) 可以是一個純數值

    a(1) 下面可以有多層陣列,並不限定為一維

    a(2) 下面只有放一層一維陣列

     

    所以取得 a(1) 下面多維陣列的上限:

    UBound(a(1)(4), 2) 取得二維陣列的第二維上標索引值。

    2008年1月23日 上午 05:41
    版主
  • 補充:

    這才是前面所稱這種陣列的彈性比較大的原因。

     

    其它:

    物件集合也可以這樣用,除了物件集合不能像陣列一樣做成多維的外。

     

    在 VB6 物件集合的效能會比陣列差,而且記憶體每一層會多使用約 60 bytes ,在 .Net framework 下微軟並沒有公開變數記憶體使用的方式,所以這部分不知道差異量,此外,.Net framework 下物件存取的效能比 VB6 增加了 4 倍以上,所以在多層一維的狀況,也有不少人喜歡用物件集合。

     

    在 .Net 內的各基礎物件中可以看出,很多物件都是用集合物件來增加層數,比如說:

    DataSet -> DataTable -> Rows -> Items

     

    2008年1月23日 上午 05:48
    版主