共用方式為


Visual Basic 中的陣列

「陣列」(Array) 是一組邏輯相關值,例如文法學校中每一年級的學生數。

藉由使用陣列,您可以透過相同名稱參考這些相關值,並使用稱為「索引」(Index) 或「註標」(Subscript) 的數字來加以區分。 這些個別值稱為陣列的「元素」(Element)。 它們是從索引 0 到最高索引值的連續值。

相對於陣列,包含單一值的變數稱為「純量」(Scalar) 變數。

本主題內容

  • 簡單陣列中的陣列項目

  • 建立陣列

  • 宣告陣列

  • 在陣列中儲存值

  • 在陣列填入初始值

    • 巢狀陣列常值
  • 逐一查看陣列

  • 做為傳回值和參數的陣列

  • 不規則陣列

  • 長度為零的陣列

  • 陣列大小

  • 陣列類型及其他類型

  • 使用集合取代陣列

簡單陣列中的陣列項目

下列範例宣告含有文法學校中每一年級學生數目的陣列變數。

Dim students(6) As Integer

前述範例中的陣列 students 包含了七個元素。 元素的索引範圍從 0 到 6。 含有此陣列較宣告七個不同的變數來得簡單。

下圖顯示陣列 students。 對於陣列的每一元素︰

  • 元素的索引表示年級 (索引 0 表示幼稚園)。

  • 元素包含的值表示該年級的學生數目。

"students" 陣列的元素

顯示學生人數之陣列的圖片

下列範例說明參考陣列 students 的第一、第二和最後一個元素的方法。

Dim kindergarten As Integer = students(0)
Dim firstGrade As Integer = students(1)
Dim sixthGrade As Integer = students(6)
MsgBox("Students in kindergarten = " & CStr(kindergarten))
MsgBox("Students in first grade = " & CStr(firstGrade))
MsgBox("Students in sixth grade = " & CStr(sixthGrade))

您可以只使用沒有索引的陣列變數名稱來當做整個陣列的參考。

前述範例中的陣列 students 使用一個索引,也就是一維 (One-dimensional)。 使用一個以上的索引或註標則稱為「多維」(Multidimensional)。 如需詳細資訊,請參閱本主題其他部分和Visual Basic 中的陣列維度

建立陣列

您可以使用數種方式來定義陣列的大小。 您可以在宣告陣列時提供大小,如下列範例所示。

Dim cargoWeights(10) As Double 
Dim atmospherePressures(2, 2, 4, 10) As Short 
Dim inquiriesByYearMonthDay(20)()() As Byte

您也可以在建立陣列時使用 New 子句提供陣列大小,如下列範例所示。

cargoWeights = New Double(10) {}
atmospherePressures = New Short(2, 2, 4, 10) {}
inquiriesByYearMonthDay = New Byte(20)()() {}

如果您有現有的陣列,可以使用 Redim 陣述式來重新定義其大小。 您可以指定 Redim 陳述式應保留陣列中的值,也可以指定建立空的新陣列。 下列範例顯示 Redim 陳述式的不同使用方法,以修改現有陣列的大小。

' Assign a new array size and retain the current element values. 
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five element values. 
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values. 
ReDim cargoWeights(15)

如需詳細資訊,請參閱ReDim 陳述式 (Visual Basic)

宣告陣列

您可使用 Dim 陳述式 (Statement) 來宣告陣列變數,方式和其他變數相同。 您可以在類型或變數名稱後面加上一組或多組括號,表示其將保存陣列而非純量 (即包含單一值的變數)。

在您宣告陣列之後,您可以使用 ReDim 陳述式 (Visual Basic) 定義其大小。

下列範例藉由在類型後面加上一組括號,宣告一維陣列變數。 範例也會使用 ReDim 陳述式 (Visual Basic) 指定陣列的維度。

' Declare a one-dimensional array. 
Dim cargoWeights As Double()

' Dimension the array. 
ReDim cargoWeights(15)

下列範例會藉由在類型之後加入一組括號,並在括號內放置逗點以分隔維度的方式,宣告多維陣列變數。 範例也會使用 ReDim 陳述式 (Visual Basic) 指定陣列的維度。

' Declare a multidimensional array. 
Dim atmospherePressures As Short(,,,)

' Dimension the array. 
ReDim atmospherePressures(1, 2, 3, 4)

若要宣告不規則陣列變數,請在變數名稱後面,為每一層巢狀陣列各新增一組括號。

Dim inquiriesByYearMonthDay()()() As Byte

前述範例只宣告陣列變數,但是未對其指派陣列。 您仍然必須建立陣列,將它初始化,然後將其指派給變數。

在陣列中儲存值

您可以使用類型為 Integer 的索引來存取陣列中的每一個位置。 您可以使用以括號括住的陣列索引參照每一個陣列位置,儲存和擷取陣列值。 多維陣列的索引以逗號 (,) 分隔。 每個陣列維度需要一個索引。 下列範例顯示一些將值儲存在陣列中的陳述式 (Statement)。

Dim i = 4
Dim j = 2

Dim numbers(10) As Integer 
Dim matrix(5, 5) As Double

numbers(i + 1) = 0
matrix(3, j * 2) = j

下列範例顯示一些從陣列中取得值的陳述式 (Statement)。

Dim v = 2
Dim i = 1
Dim j = 1
Dim k = 1
Dim wTotal As Double = 0.0
Dim sortedValues(5), rawValues(5), estimates(2, 2, 2) As Double 
Dim lowestValue = sortedValues(0)
wTotal += (rawValues(v) ^ 2)
Dim firstGuess = estimates(i, j, k)

在陣列填入初始值

您可以使用陣列常值來建立含有一組初始值的陣列。 陣列常值由大括號 ({}) 括住的逗點分隔值清單構成。

當您使用陣列常值來建立陣列時,可以提供陣列類型 (Array Type) 或者使用類型推斷來判別陣列類型。 下列程式碼顯示這兩種選項。

Dim numbers = New Integer() {1, 2, 4, 8}
Dim doubles = {1.5, 2, 9.9, 18}

使用類型推斷時,陣列的類型是由提供當做陣列常值之值清單中的主類型決定。 「主類型」(Dominant Type) 是陣列常值中的所有其他類型所擴展至其中的唯一類型。 如果無法決定此唯一類型,則主類型將成為陣列中所有其他類型可以縮小至的唯一類型。 如果無法決定所有這些類型,則主類型為 Object。 例如,如果提供給陣列常值的值清單含有類型值 Integer、Long 和 Double,則結果陣列的類型是 Double。 Integer 和 Long 都只會擴展為 Double。 因此,Double 是主類型。 如需詳細資訊,請參閱擴展和縮小轉換 (Visual Basic)。 這些推斷規則適用於針對類別成員中定義之陣列 (即區域變數) 進行的類型推斷。 雖然您可以在建立類別層級的變數時使用陣列常值,但無法在該類別層級使用類型推斷。 因此,在類別層級指定的陣列常值,會將提供當做陣列常值之值的類型推斷為 Object。

您可以明確指定使用陣列常值建立之陣列的項目類型。 在這種情況下,陣列常值中的值必須擴展為陣列元素類型。 下列程式碼範例將從整數清單建立類型為 Double 的陣列。

Dim values As Double() = {1, 2, 3, 4, 5, 6}

巢狀陣列常值

您可以使用巢狀陣列常值來建立多維陣列。 巢狀陣列常值必須具有一個維度與稱為「順位」(Rank) 的維度數目,該維度數目必須和結果陣列一致。 下列程式碼範例將使用陣列常值建立整數的二維陣列。

Dim grid = {{1, 2}, {3, 4}}

在前面範例中,如果巢狀陣列常值中的元素數量不一致,將會發生錯誤。 如果陣列變數明確宣告為非二維,也會發生錯誤。

注意事項注意事項

您可以在提供不同維度之巢狀陣列常值時,使用括號括住內部陣列常值來避免錯誤。括號將強制評估陣列常值運算式,結果值則用於外部陣列常值,如下列程式碼所示。

Dim values = {({1, 2}), ({3, 4, 5})}

使用巢狀陣列常值來建立多維陣列時,可以使用類型推斷。 當您使用類型推斷時,推斷的類型是某個巢狀層次之所有陣列常值中所有值的主類型。 下列程式碼範例將從類型為 Integer 和 Double 的值建立類型為 Double 的二維陣列。

Dim a = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}

如需其他範例,請參閱 如何:在 Visual Basic 中初始化陣列變數

逐一查看陣列

當您逐一查看陣列時,您從最低的索引到最高的索引來存取陣列中的每個項目。

下列範例會使用 For...Next 陳述式 (Visual Basic) 逐一查看一維陣列。 GetUpperBound 方法會傳回索引可具有的最大值。 最小的索引值一律為 0。

Dim numbers = {10, 20, 30}

For index = 0 To numbers.GetUpperBound(0)
    Debug.WriteLine(numbers(index))
Next 
' Output: 
'  10 
'  20 
'  30

下列範例會使用 For...Next 陳述式逐一查看多維陣列。 GetUpperBound 方法具有指定維度的參數。 GetUpperBound(0) 會傳回第一個維度的最高索引值,而 GetUpperBound(1) 會傳回第二個維度的最高索引值。

Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

For index0 = 0 To numbers.GetUpperBound(0)
    For index1 = 0 To numbers.GetUpperBound(1)
        Debug.Write(numbers(index0, index1).ToString & " ")
    Next
    Debug.WriteLine("")
Next 
' Output  
'  1 2  
'  3 4  
'  5 6

下列範例會使用 For Each...Next 陳述式 (Visual Basic) 逐一查看一維陣列。

Dim numbers = {10, 20, 30}

For Each number In numbers
    Debug.WriteLine(number)
Next 
' Output: 
'  10 
'  20 
'  30

下列範例會使用 For Each...Next 陳述式逐一查看多維陣列。 不過,如果您使用巢狀 For…Next 陳述式 (如上述範例),而不是 For Each…Next 陳述式,就能更充分控制多維陣列中的元素。

Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

For Each number In numbers
    Debug.WriteLine(number)
Next 
' Output: 
'  1 
'  2 
'  3 
'  4 
'  5 
'  6

做為傳回值和參數的陣列

若要從 Function 程序傳回陣列,將陣列資料類型和維度數目指定為 Function 陳述式 (Visual Basic) 的傳回類型。 在函式內,使用相同的資料類型和維度數目來宣告區域陣列變數。 在 Return 陳述式 (Visual Basic) 中,加入沒有括號的區域陣列變數。

若要指定陣列當做參數傳遞給 Sub 或 Function 程序,請定義參數做為具有所指定的資料類型和維度數目的陣列。 在對程序的呼叫中,傳送具有相同資料類型和維數的陣列變數。

在下列範例中,Integer() 函式會傳回 GetNumbers。 這個陣列類型是類型 Integer 的一維陣列。 ShowNumbers 程序接受 Integer() 引數。

Public Sub Process()
    Dim numbers As Integer() = GetNumbers()
    ShowNumbers(numbers)
End Sub 

Private Function GetNumbers() As Integer()
    Dim numbers As Integer() = {10, 20, 30}
    Return numbers
End Function 

Private Sub ShowNumbers(numbers As Integer())
    For index = 0 To numbers.GetUpperBound(0)
        Debug.WriteLine(numbers(index) & " ")
    Next 
End Sub 

' Output: 
'   10 
'   20 
'   30

在下列範例中,Integer(,) 函式會傳回 GetNumbersMultiDim。 這個陣列類型是類型 Integer 的二維陣列。ShowNumbersMultiDim 程序接受 Integer(,) 引數。

Public Sub ProcessMultidim()
    Dim numbers As Integer(,) = GetNumbersMultidim()
    ShowNumbersMultidim(numbers)
End Sub 

Private Function GetNumbersMultidim() As Integer(,)
    Dim numbers As Integer(,) = {{1, 2}, {3, 4}, {5, 6}}
    Return numbers
End Function 

Private Sub ShowNumbersMultidim(numbers As Integer(,))
    For index0 = 0 To numbers.GetUpperBound(0)
        For index1 = 0 To numbers.GetUpperBound(1)
            Debug.Write(numbers(index0, index1).ToString & " ")
        Next
        Debug.WriteLine("")
    Next 
End Sub 

' Output   
'  1 2   
'  3 4   
'  5 6

不規則陣列

項目已知為陣列或不規則陣列時保留其他陣列的陣列。 不規則陣列和不規則陣列中的每個項目可以有一或多個維度。 有時候應用程式中的資料結構會是非矩形的二維陣列。

下列範例包含一個月份陣列,而該陣列的每個元素則是日期陣列。 由於不同月份的天數也不同,因此這些項目不會形成矩形的二維陣列。 因此使用不規則陣列,而非多維陣列。

' Declare the jagged array. 
' The New clause sets the array variable to a 12-element 
' array. Each element is an array of Double elements. 
Dim sales()() As Double = New Double(11)() {}

' Set each element of the sales array to a Double 
' array of the appropriate size. 
For month As Integer = 0 To 11
    Dim days As Integer =
        DateTime.DaysInMonth(Year(Now), month + 1)
    sales(month) = New Double(days - 1) {}
Next month

' Store values in each element. 
For month As Integer = 0 To 11
    Dim upper = sales(month).GetUpperBound(0)
    For day = 0 To upper
        sales(month)(day) = (month * 100) + day
    Next 
Next

長度為零的陣列

沒有任何項目的陣列也稱為長度為零的陣列。 含有長度為零之陣列的變數並不會具有 Nothing 值。 若要建立沒有項目的陣列,請將陣列的其中一個維度宣告為 -1,如下列範例所示。

Dim twoDimensionalStrings(-1, 3) As String

在下列情況中,您可能需要建立長度為零的陣列:

  • 為了避免發生 NullReferenceException 例外狀況,程式碼必須存取 Array 類別的成員 (例如 LengthRank),或者呼叫 Visual Basic 函式 (例如 UBound)。

  • 您希望不需檢查 Nothing (以特殊情況處理),讓使用程式碼更簡單。

  • 程式碼會與應用程式開發介面互動,這個介面會要求您傳遞長度為零的陣列給一個或多個程序,或從一個或多個程序傳回長度為零的陣列。

陣列大小

陣列大小為其所有維度 (Dimension) 長度之乘積。 它代表目前包含於陣列中的元素總數。

下列範例宣告一個三維陣列︰

Dim prices(3, 4, 5) As Long

變數 prices 陣列的整體大小為 (3 + 1) x (4 + 1) x (5 + 1) = 120。

您可以使用 Length 屬性來尋找陣列的大小。 您也可以使用 GetLength 方法來尋找多維陣列中每一維的長度。

您可以指派新的陣列物件或者使用 ReDim 陳述式來調整陣列變數的大小。

處理陣列大小時,請注意幾點︰

維度長度

每個維度的索引都以 0 為起點,也就是它的範圍是由 0 到它的上限 (Upper Bound)。 因此,指定維度的長度會比該維度的宣告上限多 1。

長度限制

每個陣列之維度長度都受限於 Integer 資料類型的最大值,也就是 (2 ^ 31) - 1。 然而,陣列之總大小也同時受限於系統可用的記憶體。 若您試圖對總大小超過可用的 RAM 之陣列進行初始化,Common Language Runtime 將擲回 OutOfMemoryException 例外狀況。

大小及元素大小

陣列大小與其元素的資料類型無關。 大小永遠是指元素的總數,而不是它們於儲存體中所佔的位元組。

記憶體消耗量

對陣列在記憶體中的儲存方式做任何假設都是不安全的。 儲存體會因不同資料寬度的平台而有差異,所以相同陣列於 64 位元系統上所佔記憶體將較 32 位元系統來的多。 當您初始化陣列時,隨著系統組態不同,Common Language Runtime (CLR) 會指派儲存體盡可能將元素存放在一起,或是根據實體硬體界限將它們全部加以調整。 同時,陣列需要耗用儲存體以供其控制資訊使用,此消耗量會隨著維度增加而增加。

陣列類型及其他類型

每個陣列都具有其資料類型,但此資料類型不同於陣列元素的資料類型。 沒有任何單一的資料類型適用於所有的陣列。 陣列的類型是由陣列的維度數目 (或稱為「順位」(Rank) 以及陣列元素的資料類型決定。 只要兩個陣列變數具有相同順位且其元素具有相同的資料類型,就會視為具有相同的資料類型。 陣列中維度的長度不會影響陣列的資料類型。

每個陣列繼承自 Array 類別,且可將變數宣告為類型 Array,但您不能建立類型為 Array 變數。 同時,ReDim 陳述式 (Visual Basic) 無法在類型宣告為 Array 的變數上運作。 由於這些原因及類型安全,建議您將每個陣列宣告為特定類型,如前述範例中的 Integer。

有幾個方法可以找出陣列或其元素的資料類型。

  • 您可以在變數上呼叫 Object.GetType 方法,以接收變數的執行階段類型的 Type 物件。 Type 物件在其屬性和方法中保留了大量的資訊。

  • 您可以將變數傳遞給 TypeName 函式,以接收包含執行階段類型名稱的 String。

  • 您可以將變數傳遞給 VarType 函式,以接收表示變數類型類別的 VariantType 值。

下列範例呼叫 TypeName 函式來判斷陣列的類型以及陣列中元素的類型。 陣列類型為 Integer(,),陣列中元素的類型為 Integer。

Dim thisTwoDimArray(,) As Integer = New Integer(9, 9) {}
MsgBox("Type of thisTwoDimArray is " & TypeName(thisTwoDimArray))
MsgBox("Type of thisTwoDimArray(0, 0) is " & TypeName(thisTwoDimArray(0, 0)))

使用集合取代陣列

陣列是最適用於建立和處理固定數目的強類型 (Strongly Typed) 物件。 集合會提供較具彈性的方式來使用物件群組。 與陣列不同的是,您使用的物件群組可依程式變更的需要來動態增減。

如果必須變更陣列的大小,請務必使用 ReDim 陳述式 (Visual Basic)。 當您這麼做時,Visual Basic 會建立新的陣列,並釋出先前的陣列以供處置 (Dispose)。 這將佔用執行時間。 因此,如果您處理的項目數經常變更,或無法預測需要的最大項目數,您可以使用集合來達到較佳的效能。

對於某些集合,您可以將索引鍵指派給您放入集合的任何物件,讓您可以藉由使用索引鍵快速擷取物件。

如果集合包含只有一個資料類型的項目,則可使用 System.Collections.Generic 命名空間內的其中一個類別。 「泛型」(Generic) 集合會強制「類型安全」(Type Safety),如此就不會加入其他資料類型。 當您從泛型集合中擷取元素,並不需要判斷其資料類型或將之轉換。

如需集合的詳細資訊,請參閱 集合 (C# 和 Visual Basic)

範例

下列範例使用 .NET Framework 泛型類別 List 來建立 Customer 物件的清單集合。

' Define the class for a customer. 
Public Class Customer
    Public Property Name As String 
    ' Insert code for other members of customer structure. 
End Class 

' Create a module-level collection that can hold 200 elements. 
Public CustomerList As New List(Of Customer)(200)

' Add a specified customer to the collection. 
Private Sub AddNewCustomer(ByVal newCust As Customer)
    ' Insert code to perform validity check on newCust.
    CustomerList.Add(newCust)
End Sub 

' Display the list of customers in the Debug window. 
Private Sub PrintCustomers()
    For Each cust As Customer In CustomerList
        Debug.WriteLine(cust)
    Next cust
End Sub

CustomerFile 集合的宣告指定它僅可包含類型 Customer 的項目。 同時也提供 200 個項目的初始容量。 程序 AddNewCustomer 會檢查新項目的有效性,然後將它加入集合中。 程序 PrintCustomers 會使用 For Each 迴圈以便穿越集合並顯示項目。

相關主題

詞彙

定義

Visual Basic 中的陣列維度

說明陣列中的陣序規範和維度 (Dimension)。

如何:在 Visual Basic 中初始化陣列變數

描述如何在陣列中填入初始值。

如何:在 Visual Basic 中排序陣列

示範如何依字母順序排列陣列中的元素。

如何:指派一個陣列至另一個陣列 (Visual Basic)

描述將陣列指派給另一個陣列變數的規則和步驟。

疑難排解陣列 (Visual Basic)

討論在使用陣列時會引發的一些常見問題。

請參閱

參考

Dim 陳述式 (Visual Basic)

ReDim 陳述式 (Visual Basic)

Array