Udostępnij za pośrednictwem


Tablice w Visual Basic

Tablica to zbiór wartości, które są ze sobą logicznie powiązane i nazywane elementami. Na przykład tablica może składać się z liczby uczniów w każdej klasie w gimnazjum; każdy element tablicy jest liczbą uczniów w jednej klasie. Podobnie tablica może składać się z ocen ucznia z przedmiotu; każdy element tablicy jest pojedynczą oceną.

Istnieje możliwość użycia poszczególnych zmiennych do przechowywania każdego z naszych elementów danych. Jeśli na przykład nasza aplikacja analizuje oceny uczniów, możemy użyć oddzielnej zmiennej dla klasy każdego ucznia, takiej jak englishGrade1, englishGrade2itp. Takie podejście ma trzy główne ograniczenia:

  • Musimy wiedzieć na etapie projektowania dokładnie, ile rodzajów ocen musimy obsłużyć.
  • Zarządzanie dużą liczbą ocen szybko staje się kłopotliwe. To z kolei sprawia, że aplikacja ma znacznie większe prawdopodobieństwo wystąpienia poważnych usterek.
  • Trudno jest to utrzymać. Każda nowa ocena, którą dodamy, wymaga zmodyfikowania, ponownego skompilowania i ponownego wdrożenia aplikacji.

Korzystając z tablicy, można odwoływać się do tych powiązanych wartości o tej samej nazwie i użyć liczby nazywanej indeksem lub indeksem dolnym , aby zidentyfikować pojedynczy element na podstawie jego pozycji w tablicy. Indeksy tablicy wahają się od 0 do jednej mniejszej niż całkowita liczba elementów w tablicy. Gdy używasz składni języka Visual Basic do definiowania rozmiaru tablicy, należy określić jej najwyższy indeks, a nie całkowitą liczbę elementów w tablicy. Możesz pracować z tablicą jako jednostką, a możliwość iterowania jej elementów uwalnia od potrzeb, aby wiedzieć dokładnie, ile elementów zawiera w czasie projektowania.

Kilka szybkich przykładów przed wyjaśnieniem:

' Declare a single-dimension array of 5 numbers.
Dim numbers(4) As Integer

' Declare a single-dimension array and set its 4 values.
Dim numbers = New Integer() {1, 2, 4, 8}

' Change the size of an existing array to 16 elements and retain the current values.
ReDim Preserve numbers(15)

' Redefine the size of an existing array and reset the values.
ReDim numbers(15)

' Declare a 6 x 6 multidimensional array.
Dim matrix(5, 5) As Double

' Declare a 4 x 3 multidimensional array and set array element values.
Dim matrix = New Integer(,) {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}

' Declare a jagged array
Dim sales()() As Double = New Double(11)() {}

Elementy tablicy w prostej tablicy

Utwórzmy tablicę o nazwie students , aby przechowywać liczbę uczniów w każdej klasie w gimnazjum. Indeksy elementów wahają się od 0 do 6. Użycie tej tablicy jest prostsze niż deklarowanie siedmiu zmiennych.

Poniższa ilustracja przedstawia tablicę students . Dla każdego elementu tablicy:

  • Indeks elementu reprezentuje klasę (indeks 0 reprezentuje przedszkole).

  • Wartość zawarta w elemencie reprezentuje liczbę uczniów w tej klasie.

Diagram przedstawiający tablicę liczb uczniów

Poniższy przykład zawiera kod języka Visual Basic, który tworzy tablicę i używa jej:


Module SimpleArray
   Public Sub Main()
      ' Declare an array with 7 elements.
      Dim students(6) As Integer

      ' Assign values to each element.
      students(0) = 23
      students(1) = 19
      students(2) = 21
      students(3) = 17
      students(4) = 19
      students(5) = 20
      students(6) = 22
      
      ' Display the value of each element.
      For ctr As Integer = 0 To 6
         Dim grade As String = If(ctr = 0, "kindergarten", $"grade {ctr}")
         Console.WriteLine($"Students in {grade}: {students(ctr)}")
      Next
   End Sub
End Module
' The example displays the following output:
'     Students in kindergarten: 23
'     Students in grade 1: 19
'     Students in grade 2: 21
'     Students in grade 3: 17
'     Students in grade 4: 19
'     Students in grade 5: 20
'     Students in grade 6: 22

W przykładzie przedstawiono trzy elementy:

  • Deklaruje tablicę students z siedmioma elementami. Liczba 6 w deklaracji tablicy wskazuje ostatni indeks w tablicy; jest jedną mniejszą niż liczba elementów w tablicy.
  • Przypisuje wartości do każdego elementu w tablicy. Dostęp do elementów tablicy jest uzyskiwany przy użyciu nazwy tablicy i dołączania indeksu pojedynczego elementu w nawiasach.
  • Wyświetla każdą wartość tablicy. W przykładzie użyto For instrukcji w celu uzyskania dostępu do każdego elementu tablicy według jego numeru indeksu.

Tablica students w poprzednim przykładzie jest tablicą jednowymiarową, ponieważ używa jednego indeksu. Tablica używająca więcej niż jednego indeksu lub indeksa dolnego jest nazywana wielowymiarowa. Aby uzyskać więcej informacji, zobacz pozostałe części tego artykułu i Wymiary tablicy w Visual Basic.

Tworzenie tablicy

Rozmiar tablicy można zdefiniować na kilka sposobów:

  • Rozmiar można określić, gdy tablica jest zadeklarowana:

    ' Declare an array with 10 elements.
    Dim cargoWeights(9) As Double               
    ' Declare a 24 x 2 array.
    Dim hourlyTemperatures(23, 1) As Integer
    ' Declare a jagged array with 31 elements.
    Dim januaryInquiries(30)() As String
    
  • Możesz użyć New klauzuli , aby podać rozmiar tablicy podczas jej tworzenia:

    ' Declare an array with 10 elements.
    Dim cargoWeights() As Double = New Double(9) {}
    ' Declare a 24 x 2 array.
    Dim hourlyTemperatures(,) As Integer = New Integer(23, 1) {}
    ' Declare a jagged array with 31 elements. 
    Dim januaryInquiries()() As String = New String(30)() {}
    

Jeśli masz istniejącą tablicę, możesz ponownie zdefiniować jej rozmiar przy użyciu instrukcji ReDim . Można określić, że ReDim instrukcja przechowuje wartości, które znajdują się w tablicy, lub można określić, że tworzy pustą tablicę. W poniższym przykładzie pokazano różne zastosowania instrukcji ReDim w celu zmodyfikowania rozmiaru istniejącej tablicy.

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

Aby uzyskać więcej informacji, zobacz instrukcję ReDim.

Przechowywanie wartości w tablicy

Dostęp do każdej lokalizacji w tablicy można uzyskać przy użyciu indeksu typu Integer. Wartości w tablicy można przechowywać i pobierać, odwołując się do każdej lokalizacji tablicy, używając jej indeksu ujętego w nawiasy. Indeksy dla tablic wielowymiarowych są oddzielone przecinkami (,). Potrzebujesz jednego indeksu dla każdego wymiaru tablicy.

W poniższym przykładzie przedstawiono niektóre polecenia, które przechowują i pobierają wartości w tablicach.


Module Example
   Public Sub Main()
      ' Create a 10-element integer array.
      Dim numbers(9) As Integer
      Dim value As Integer = 2
        
      ' Write values to it.
      For ctr As Integer = 0 To 9
         numbers(ctr) = value
         value *= 2
      Next
        
      ' Read and sum the array values.  
      Dim sum As Integer
      For ctr As Integer = 0 To 9
         sum += numbers(ctr)
      Next
      Console.WriteLine($"The sum of the values is {sum:N0}")
    End Sub
End Module
' The example displays the following output:
'     The sum of the values is 2,046

Wypełnianie tablicy literałami tablicowymi

Używając literału tablicy, można jednocześnie utworzyć i wypełnić tablicę początkowym zestawem wartości. Literał tablicy składa się z listy wartości rozdzielanych przecinkami, ujętych w nawiasy klamrowe ({}).

Podczas tworzenia tablicy przy użyciu literału tablicy można podać typ tablicy lub użyć inferencji typu w celu ustalenia typu tablicy. W poniższym przykładzie przedstawiono obie opcje.

' Array literals with explicit type definition.
Dim numbers = New Integer() {1, 2, 4, 8}
' Array literals with type inference.
Dim doubles = {1.5, 2, 9.9, 18}
' Array literals with explicit type definition.
Dim articles() As String = { "the", "a", "an" }

' Array literals with explicit widening type definition.
Dim values() As Double = { 1, 2, 3, 4, 5 }

Gdy używasz wnioskowania typu, typ tablicy jest określany przez dominujący typ na liście literałów wartości. Typ dominujący to typ, do którego można poszerzyć wszystkie inne typy w tablicy. Jeśli tego unikalnego typu nie można określić, typ dominujący jest unikalnym typem, do którego wszystkie inne typy w tablicy mogą się zawęzić. Jeśli nie można określić żadnego z tych unikatowych typów, dominujący typ to Object. Jeśli na przykład lista wartości dostarczonych do literału tablicy zawiera wartości typu Integer, Longi Double, wynikowa tablica jest typu Double. Ponieważ Integer i Long poszerzają się tylko do Double, Double jest dominującym rodzajem. Aby uzyskać więcej informacji, zobacz Rozszerzanie i zawężanie konwersji.

Uwaga / Notatka

Możesz użyć wnioskowania typu tylko dla tablic, które są zdefiniowane jako lokalne zmienne w jednostce typu. Jeśli jawna definicja typu jest nieobecna, tablice zdefiniowane z literałami tablicy na poziomie klasy są typu Object[]. Aby uzyskać więcej informacji, zobacz Wnioskowanie typu lokalnego.

Należy pamiętać, że w poprzednim przykładzie zdefiniowano values jako tablicę typu Double , mimo że wszystkie literały tablicy mają typ Integer. Tę tablicę można utworzyć, ponieważ wartości w literale tablicy mogą być rozszerzane na Double wartości.

Również można utworzyć i wypełnić tablicę wielowymiarową, korzystając z zagnieżdżonych literałów tablicy. Zagnieżdżone literały tablicy muszą mieć liczbę wymiarów zgodną z wymiarami wynikowej tablicy. Poniższy przykład przedstawia tworzenie dwuwymiarowej tablicy liczb całkowitych poprzez użycie zagnieżdżonych literałów tablicowych.

' Create and populate a 2 x 2 array.
Dim grid1 = {{1, 2}, {3, 4}}
' Create and populate a 2 x 2 array with 3 elements.
Dim grid2(,) = {{1, 2}, {3, 4}, {5, 6}}

W przypadku używania zagnieżdżonych literałów tablicy do tworzenia i wypełniania tablicy występuje błąd, jeśli liczba elementów w zagnieżdżonych literałach tablicy nie jest zgodna. Błąd występuje również, jeśli jawnie zadeklarujesz zmienną tablicową z inną liczbą wymiarów niż literały tablicy.

Podobnie jak w przypadku tablic jednowymiarowych, można polegać na wnioskowaniu typu podczas tworzenia tablicy wielowymiarowej za pomocą zagnieżdżonych literałów tablicowych. Wywnioskowany typ jest dominującym typem dla wszystkich wartości we wszystkich literałach tablicy dla wszystkich poziomów zagnieżdżania. Poniższy przykład tworzy dwuwymiarową tablicę typu Double[,] na podstawie wartości typu Integer i Double.

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

Aby uzyskać dodatkowe przykłady, zobacz How to: Initialize an Array Variable in Visual Basic (Jak zainicjować zmienną tablicową w Visual Basic).

Iterowanie za pomocą tablicy

Podczas iterowania tablicy uzyskujesz dostęp do każdego elementu w tablicy z najniższego indeksu do najwyższego lub najwyższego do najniższego. Zazwyczaj używa się instrukcji For...Next lub For Each...Next do przechodzenia przez elementy tablicy. Jeśli nie znasz górnych granic tablicy, możesz wywołać metodę Array.GetUpperBound , aby uzyskać najwyższą wartość indeksu. Chociaż najniższa wartość indeksu jest prawie zawsze 0, można wywołać Array.GetLowerBound metodę , aby uzyskać najniższą wartość indeksu.

Poniższy przykład przechodzi przez tablicę jednowymiarową przy użyciu instrukcji For...Next.


Module IterateArray
   Public Sub Main()
      Dim numbers = {10, 20, 30}

      For index = 0 To numbers.GetUpperBound(0)
         Console.WriteLine(numbers(index))
      Next
   End Sub
End Module
' The example displays the following output:
'  10
'  20
'  30

Poniższy przykład przechodzi przez tablicę wielowymiarową przy użyciu For...Next instrukcji. Metoda GetUpperBound ma parametr określający wymiar. GetUpperBound(0) Zwraca najwyższy indeks pierwszego wymiaru i GetUpperBound(1) zwraca najwyższy indeks drugiego wymiaru.


Module IterateArray
   Public Sub Main()
      Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

      For index0 = 0 To numbers.GetUpperBound(0)
         For index1 = 0 To numbers.GetUpperBound(1)
            Console.Write($"{numbers(index0, index1)} ")
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
' Output 
'  1 2 
'  3 4 
'  5 6

W poniższym przykładzie użyto instrukcji For Each...Next do iteracji przez tablicę jednowymiarową i dwuwymiarową.


Module IterateWithForEach
   Public Sub Main()
      ' Declare and iterate through a one-dimensional array.
      Dim numbers1 = {10, 20, 30}
      
      For Each number In numbers1
         Console.WriteLine(number)
      Next
      Console.WriteLine()
      
      Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

      For Each number In numbers
         Console.WriteLine(number)
      Next
   End Sub
End Module
' The example displays the following output:
'  10
'  20
'  30
'
'  1
'  2
'  3
'  4
'  5
'  6

Rozmiar tablicy

Rozmiar tablicy jest iloczynem długości wszystkich jej wymiarów. Reprezentuje całkowitą liczbę elementów znajdujących się obecnie w tablicy. Na przykład poniższy przykład deklaruje tablicę dwuwymiarową z czterema elementami w każdym wymiarze. Jak pokazuje wynik przykładu, rozmiar tablicy wynosi 16 (lub (3 + 1) * (3 + 1).


Module Example
   Public Sub Main()
      Dim arr(3, 3) As Integer
      Console.WriteLine(arr.Length)     
   End Sub
End Module
' The example displays the following output:
'     16

Uwaga / Notatka

Ta dyskusja na temat rozmiaru tablicy nie ma zastosowania do tablic postrzępionych. Aby uzyskać informacje na temat tablic postrzępionych i określania rozmiaru tablicy postrzępionej, zobacz sekcję Tablice postrzępione .

Rozmiar tablicy można znaleźć przy użyciu Array.Length właściwości . Długość każdego wymiaru tablicy wielowymiarowej można znaleźć przy użyciu Array.GetLength metody .

Możesz zmienić rozmiar zmiennej tablicy, przypisując do niej nowy obiekt tablicy lub używając instrukcji ReDim . W poniższym przykładzie użyto instrukcji ReDim , aby zmienić tablicę 100-element na tablicę 51-elementową.


Module Example
   Public Sub Main()
      Dim arr(99) As Integer
      Console.WriteLine(arr.Length)
      
      Redim arr(50)
      Console.WriteLine(arr.Length)
   End Sub
End Module
' The example displays the following output:
'     100
'     51

 

Podczas radzenia sobie z rozmiarem tablicy należy pamiętać o kilku kwestiach.

Notatki
Długość wymiaru Indeks każdego wymiaru jest oparty na 0, co oznacza, że waha się od 0 do górnej granicy. W związku z tym długość danego wymiaru jest większa niż zadeklarowana górna granica tego wymiaru.
Limity długości Długość każdego wymiaru tablicy jest ograniczona do maksymalnej wartości Integer typu danych, czyli Int32.MaxValue (2 ^ 31) – 1. Jednak całkowity rozmiar tablicy jest również ograniczony przez pamięć dostępną w systemie. Jeśli spróbujesz zainicjalizować tablicę, która przekracza dostępną ilość pamięci, środowisko uruchomieniowe zgłasza OutOfMemoryException.
Rozmiar i rozmiar elementu Rozmiar tablicy jest niezależny od typu danych jego elementów. Rozmiar zawsze reprezentuje całkowitą liczbę elementów, a nie liczbę bajtów używanych w pamięci.
Zużycie pamięci Nie można bezpiecznie założyć żadnych założeń dotyczących sposobu przechowywania tablicy w pamięci. Pamięć różni się na platformach o różnych architekturach danych, więc ta sama tablica może zajmować więcej pamięci na 64-bitowym systemie niż na 32-bitowym. W zależności od konfiguracji systemu podczas inicjowania tablicy środowisko uruchomieniowe języka wspólnego (CLR) może przypisać przestrzeń pamięci, aby upakować elementy tak blisko siebie, jak to możliwe, lub wyrównać je wszystkie na naturalnych granicach sprzętowych. Ponadto tablica wymaga narzutu pamięciowego dla danych kontrolnych, a narzut ten zwiększa się wraz z każdym dodanym wymiarem.

Typ tablicy

Każda tablica ma typ danych, który różni się od typu danych jego elementów. Nie istnieje jeden rodzaj danych dla wszystkich tablic. Zamiast tego typ danych tablicy jest określany przez liczbę wymiarów lub rangę tablicy oraz typ danych elementów w tablicy. Dwie zmienne tablicowe mają ten sam typ danych tylko wtedy, gdy mają tę samą rangę, a ich elementy mają ten sam typ danych. Długość wymiarów tablicy nie ma wpływu na typ danych tablicy.

Każda tablica dziedziczy z System.Array klasy i można zadeklarować zmienną Arraytypu , ale nie można utworzyć tablicy typu Array. Na przykład, mimo że poniższy kod deklaruje zmienną arr jako typu Array i wywołuje metodę Array.CreateInstance w celu utworzenia instancji tablicy, okazuje się, że typ tablicy to Object[].


Module Example
   Public Sub Main()
      Dim arr As Array = Array.CreateInstance(GetType(Object), 19)
      Console.WriteLine(arr.Length)
      Console.WriteLine(arr.GetType().Name)
   End Sub
End Module
' The example displays the following output:
'     19
'     Object[]

Ponadto instrukcja ReDim nie może działać na zmiennej zadeklarowanej jako typ Array. Z tych powodów i bezpieczeństwa typu zaleca się zadeklarowanie każdej tablicy jako określonego typu.

Typ danych tablicy lub jej elementów można ustalić na kilka sposobów.

  • Metodę GetType w zmiennej można wywołać, aby uzyskać Type obiekt reprezentujący typ czasu wykonywania zmiennej. Obiekt Type zawiera obszerne informacje o jego właściwościach i metodach.
  • Zmienną można przekazać do TypeName funkcji, aby uzyskać zmienną String o nazwie typu czasu wykonywania.

Poniższy przykład wywołuje zarówno metodę GetType , jak i TypeName funkcję, aby określić typ tablicy. Typ tablicy to Byte(,). Należy pamiętać, że Type.BaseType właściwość wskazuje również, że podstawowym typem tablicy bajtów jest Array klasa .


Module Example
   Public Sub Main()
      Dim bytes(9,9) As Byte
      Console.WriteLine($"Type of {nameof(bytes)} array: {bytes.GetType().Name}")
      Console.WriteLine($"Base class of {nameof(bytes)}: {bytes.GetType().BaseType.Name}")
      Console.WriteLine()
      Console.WriteLine($"Type of {nameof(bytes)} array: {TypeName(bytes)}")
   End Sub
End Module
' The example displays the following output:
' Type of bytes array: Byte[,]
' Base class of bytes: Array
' 
' Type of bytes array: Byte(,)


Tablice jako wartości zwracane i parametry

Aby zwrócić tablicę z Function procedury, określ typ danych tablicy i liczbę wymiarów jako zwracany typ instrukcji funkcji. W ramach funkcji zadeklaruj zmienną tablicy lokalnej o tym samym typie danych i liczbie wymiarów. W instrukcji return dodaj zmienną tablicy lokalnej bez nawiasów.

Aby określić tablicę jako parametr do Sub procedury lub Function , zdefiniuj parametr jako tablicę z określonym typem danych i liczbą wymiarów. W wywołaniu procedury przekaż zmienną tablicową o tym samym typie danych i liczbie wymiarów.

W poniższym przykładzie funkcja GetNumbers zwraca jednowymiarową tablicę typu Integer(). Procedura ShowNumbers akceptuje Integer() argument.


Module ReturnValuesAndParams
   Public Sub Main()
      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)
         Console.WriteLine($"{numbers(index)} ")
      Next
   End Sub
End Module
' The example displays the following output:
'   10
'   20
'   30
    

W poniższym przykładzie funkcja GetNumbersMultiDim zwraca Integer(,), tablicę dwuwymiarową typu Integer. Procedura ShowNumbersMultiDim akceptuje Integer(,) argument.


Module Example
   Public Sub Main()
      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)
            Console.Write($"{numbers(index0, index1)} ")
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'     1 2
'     3 4
'     5 6

Tablice postrzępione

Czasami struktura danych w aplikacji jest dwuwymiarowa, ale nie prostokątna. Na przykład można użyć tablicy do przechowywania danych dotyczących wysokiej temperatury każdego dnia miesiąca. Pierwszy wymiar tablicy reprezentuje miesiąc, ale drugi wymiar reprezentuje liczbę dni, a liczba dni w miesiącu nie jest jednolita. Tablica postrzępiona, nazywana również tablicą tablic, jest przeznaczona dla takich scenariuszy. Tablica postrzępiona to taki typ tablicy, w której każdy element jest osobną tablicą. Tablica postrzępiona i każdy element w tablicy postrzępionej może mieć co najmniej jeden wymiar.

W poniższym przykładzie użyto tablicy miesięcy, z których każdy element jest tablicą dni. W przykładzie użyto tablicy postrzępionej, ponieważ liczba dni w poszczególnych miesiącach się różni. W przykładzie pokazano, jak utworzyć tablicę postrzępioną, przypisać wartości, oraz jak pobierać i wyświetlać jej wartości.

Imports System.Globalization

Module JaggedArray
   Public Sub Main()
      ' Declare the jagged array of 12 elements. Each element is an array of Double.
      Dim sales(11)() As Double
      ' Set each element of the sales array to a Double array of the appropriate size.
      For month As Integer = 0 To 11
         ' The number of days in the month determines the appropriate size.
         Dim daysInMonth As Integer =
            DateTime.DaysInMonth(Year(Now), month + 1)
         sales(month) = New Double(daysInMonth - 1) {}
      Next 

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

      ' Retrieve and display the array values.
      Dim monthNames = DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames
      ' Display the month names.
      Console.Write("    ")
      For ctr = 0 To sales.GetUpperBound(0)
         Console.Write($" {monthNames(ctr)}   ")
      Next   
      Console.WriteLine()
      ' Display data for each day in each month.
      For dayInMonth = 0 To 30
         Console.Write($"{dayInMonth + 1,2}.  ")
         For monthNumber = 0 To sales.GetUpperBound(0)
            If dayInMonth > sales(monthNumber).GetUpperBound(0) Then 
               Console.Write("       ")
            Else
               Console.Write($"{sales(monthNumber)(dayInMonth),-5}  ")
            End If
         Next   
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'      Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct    Nov    Dec
'  1.  0      100    200    300    400    500    600    700    800    900    1000   1100
'  2.  1      101    201    301    401    501    601    701    801    901    1001   1101
'  3.  2      102    202    302    402    502    602    702    802    902    1002   1102
'  4.  3      103    203    303    403    503    603    703    803    903    1003   1103
'  5.  4      104    204    304    404    504    604    704    804    904    1004   1104
'  6.  5      105    205    305    405    505    605    705    805    905    1005   1105
'  7.  6      106    206    306    406    506    606    706    806    906    1006   1106
'  8.  7      107    207    307    407    507    607    707    807    907    1007   1107
'  9.  8      108    208    308    408    508    608    708    808    908    1008   1108
' 10.  9      109    209    309    409    509    609    709    809    909    1009   1109
' 11.  10     110    210    310    410    510    610    710    810    910    1010   1110
' 12.  11     111    211    311    411    511    611    711    811    911    1011   1111
' 13.  12     112    212    312    412    512    612    712    812    912    1012   1112
' 14.  13     113    213    313    413    513    613    713    813    913    1013   1113
' 15.  14     114    214    314    414    514    614    714    814    914    1014   1114
' 16.  15     115    215    315    415    515    615    715    815    915    1015   1115
' 17.  16     116    216    316    416    516    616    716    816    916    1016   1116
' 18.  17     117    217    317    417    517    617    717    817    917    1017   1117
' 19.  18     118    218    318    418    518    618    718    818    918    1018   1118
' 20.  19     119    219    319    419    519    619    719    819    919    1019   1119
' 21.  20     120    220    320    420    520    620    720    820    920    1020   1120
' 22.  21     121    221    321    421    521    621    721    821    921    1021   1121
' 23.  22     122    222    322    422    522    622    722    822    922    1022   1122
' 24.  23     123    223    323    423    523    623    723    823    923    1023   1123
' 25.  24     124    224    324    424    524    624    724    824    924    1024   1124
' 26.  25     125    225    325    425    525    625    725    825    925    1025   1125
' 27.  26     126    226    326    426    526    626    726    826    926    1026   1126
' 28.  27     127    227    327    427    527    627    727    827    927    1027   1127
' 29.  28            228    328    428    528    628    728    828    928    1028   1128
' 30.  29            229    329    429    529    629    729    829    929    1029   1129
' 31.  30            230           430           630    730           930           1130

W poprzednim przykładzie wartości są przypisywane do tablicy nieregularnej dla każdego elementu przy użyciu pętli For...Next. Można również przypisać wartości do elementów tablicy postrzępionej przy użyciu zagnieżdżonych literałów tablicy. Jednak próba użycia zagnieżdżonych literałów tablicowych (na przykład Dim valuesjagged = {{1, 2}, {2, 3, 4}}) powoduje błąd w kompilatorze BC30568. Aby poprawić błąd, należy ująć literały tablicy wewnętrznej w nawiasy. Nawiasy wymuszają obliczanie wyrażenia literału tablicy, a wynikowe wartości są używane z zewnętrznym literałem tablicy, jak pokazano w poniższym przykładzie.


Module Example
   Public Sub Main()
      Dim values1d = { 1, 2, 3 }
      Dim values2d = {{1, 2}, {2, 3}, {3, 4}}
      Dim valuesjagged = {({1, 2}), ({2, 3, 4})}
   End Sub
End Module

Jednowymiarowa tablica postrzępiona to taka, której elementy zawierają tablice. Dlatego właściwość Array.Length i metoda Array.GetLength(0) zwracają liczbę elementów w tablicy jednowymiarowej, a Array.GetLength(1) zgłasza wyjątek IndexOutOfRangeException, ponieważ tablica zygzakowata nie jest wielowymiarowa. Liczbę elementów w każdym podarrayu określa się, pobierając wartość właściwości Array.Length każdego podarrayu. W poniższym przykładzie pokazano, jak określić liczbę elementów w tablicy postrzępionej.


Module Example
   Public Sub Main()
      Dim jagged = { ({1, 2}), ({2, 3, 4}), ({5, 6}), ({7, 8, 9, 10}) }
      Console.WriteLine($"The value of jagged.Length: {jagged.Length}.")
      Dim total = jagged.Length
      For ctr As Integer = 0 To jagged.GetUpperBound(0)
         Console.WriteLine($"Element {ctr + 1} has {jagged(ctr).Length} elements.") 
         total += jagged(ctr).Length 
      Next
      Console.WriteLine($"The total number of elements in the jagged array: {total}")
   End Sub
End Module
' The example displays the following output:
'     The value of jagged.Length: 4.
'     Element 1 has 2 elements.
'     Element 2 has 3 elements.
'     Element 3 has 2 elements.
'     Element 4 has 4 elements.
'     The total number of elements in the jagged array: 15

Tablice o zerowej długości

Język Visual Basic rozróżnia tablicę niezainicjowaną (tablicę, której wartość to Nothing) oraz tablicę o zerowej długości lub pustą tablicę (tablicę, która nie ma elementów). Niezainicjowana tablica to tablica, która nie została wymiarowana lub miała przypisane do niej żadne wartości. Przykład:

Dim arr() As String

Tablica o zerowej długości jest zadeklarowana z wymiarem -1. Przykład:

Dim arrZ(-1) As String

Może być konieczne utworzenie tablicy o zerowej długości w następujących okolicznościach:

  • Bez ryzyka NullReferenceException wyjątku kod musi uzyskiwać dostęp do składowych Array klasy, takich jak Length lub Rank, lub wywołać funkcję Visual Basic, taką jak UBound.

  • Chcesz, aby kod był prosty, nie trzeba go Nothing sprawdzać jako specjalny przypadek.

  • Kod współdziała z interfejsem programowania aplikacji (API), który wymaga przekazania tablicy o zerowej długości do co najmniej jednej procedury lub zwraca tablicę o zerowej długości z co najmniej jednej procedury.

Dzielenie tablicy

W niektórych przypadkach może być konieczne podzielenie pojedynczej tablicy na wiele tablic. Obejmuje to zidentyfikowanie punktu lub punktów, w których tablica ma zostać podzielona, a następnie dzielenie tablicy na dwie lub więcej oddzielnych tablic.

Uwaga / Notatka

W tej sekcji nie omówiono dzielenia pojedynczego ciągu na tablicę ciągów na podstawie niektórych ograniczników. Aby uzyskać informacje na temat dzielenia ciągu, zobacz metodę String.Split .

Najczęstsze kryteria dzielenia tablicy to:

  • Liczba elementów w tablicy. Na przykład, można podzielić tablicę, gdy zawiera więcej niż określoną liczbę elementów, na części w przybliżeniu równe. W tym celu można użyć wartości zwracanej przez metodę Array.Length lub Array.GetLength .

  • Wartość elementu, który służy jako ogranicznik, który wskazuje, gdzie tablica powinna być podzielona. Możesz wyszukać określoną wartość, wywołując metody Array.FindIndex i Array.FindLastIndex.

Po określeniu indeksu lub indeksów, w których tablica ma zostać podzielona, można utworzyć poszczególne tablice, wywołując metodę Array.Copy .

W poniższym przykładzie tablica jest podzielona na dwie tablice o zbliżonym rozmiarze. (Jeśli łączna liczba elementów tablicy jest nieparzysta, pierwsza tablica ma jeden element więcej niż druga.)


Module Example
   Public Sub Main()
      ' Create an array of 100 elements.
      Dim arr(99) As Integer
      ' Populate the array.
      Dim rnd As new Random()
      For ctr = 0 To arr.GetUpperBound(0)
         arr(ctr) = rnd.Next()
      Next
      
      ' Determine how many elements should be in each array.
      Dim divisor = 2
      Dim remainder As Integer
      Dim boundary = Math.DivRem(arr.GetLength(0), divisor, remainder)
            
      ' Copy the array.
      Dim arr1(boundary - 1 + remainder), arr2(boundary - 1) as Integer
      Array.Copy(arr, 0, arr1, 0, boundary + remainder)
      Array.Copy(arr, boundary + remainder, arr2, 0, arr.Length - boundary) 
   End Sub
End Module

Poniższy przykład dzieli tablicę ciągów na dwie tablice na podstawie obecności elementu, którego wartość to "zzz", który służy jako ogranicznik tablicy. Nowe tablice nie zawierają elementu zawierającego ogranicznik.


Module Example
   Public Sub Main()
      Dim rnd As New Random()
      
      ' Create an array of 100 elements.
      Dim arr(99) As String
      ' Populate each element with an arbitrary ASCII character.
      For ctr = 0 To arr.GetUpperBound(0)
         arr(ctr) = ChrW(Rnd.Next(&h21, &h7F))
      Next
      ' Get a random number that will represent the point to insert the delimiter.
      arr(rnd.Next(0, arr.GetUpperBound(0))) = "zzz"

      ' Find the delimiter.
      Dim location = Array.FindIndex(arr, Function(x) x = "zzz")

      ' Create the arrays.
      Dim arr1(location - 1) As String
      Dim arr2(arr.GetUpperBound(0) - location - 1) As String
      
      ' Populate the two arrays.
      Array.Copy(arr, 0, arr1, 0, location)
      Array.Copy(arr, location + 1, arr2, 0, arr.GetUpperBound(0) - location)
   End Sub
End Module

Łączenie tablic

Można również połączyć wiele tablic w jedną większą tablicę. W tym celu należy również użyć Array.Copy metody .

Uwaga / Notatka

W tej sekcji nie omówiono łączenia tablicy ciągów w jeden ciąg. Aby uzyskać informacje na temat dołączania tablicy ciągów, zobacz metodę String.Join .

Przed skopiowaniem elementów każdej tablicy do nowej tablicy należy najpierw upewnić się, że zainicjowano tablicę tak, aby była wystarczająco duża, aby pomieścić wszystkie elementy. Można to zrobić na jeden z dwóch sposobów:

  • Użyj instrukcji ReDim Preserve , aby dynamicznie rozwinąć tablicę przed dodaniem do niej nowych elementów. Jest to najłatwiejsza technika, ale może to spowodować obniżenie wydajności i nadmierne zużycie pamięci podczas kopiowania dużych tablic.
  • Oblicz całkowitą liczbę elementów potrzebnych dla nowej dużej tablicy, a następnie dodaj do niej elementy każdej tablicy źródłowej.

W poniższym przykładzie użyto drugiego podejścia, aby dodać cztery tablice z dziesięcioma elementami do pojedynczej tablicy.

Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Integer()))
      ' Generate four arrays.
      For ctr = 0 To 3
         Dim value = ctr
         tasks.Add(Task.Run(Function()
                               Dim arr(9) As Integer
                               For ndx = 0 To arr.GetUpperBound(0)
                                  arr(ndx) = value
                               Next
                               Return arr
                            End Function))   
       Next
       Task.WaitAll(tasks.ToArray())
       ' Compute the number of elements in all arrays.
       Dim elements = 0
       For Each task In tasks
          elements += task.Result.Length
       Next
       Dim newArray(elements - 1) As Integer
       Dim index = 0
       For Each task In tasks
          Dim n = task.Result.Length
          Array.Copy(task.Result, 0, newArray, index, n)
          index += n
       Next 
      Console.WriteLine($"The new array has {newArray.Length} elements.")
   End Sub
End Module
' The example displays the following output:
'     The new array has 40 elements.

Ponieważ w tym przypadku tablice źródłowe są małe, możemy również dynamicznie rozszerzać tablicę, dodając do niej elementy każdej nowej tablicy. Poniższy przykład to robi.

Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Integer()))
      ' Generate four arrays.
      For ctr = 0 To 3
         Dim value = ctr
         tasks.Add(Task.Run(Function()
                               Dim arr(9) As Integer
                               For ndx = 0 To arr.GetUpperBound(0)
                                  arr(ndx) = value
                               Next
                               Return arr
                            End Function))   
       Next
       Task.WaitAll(tasks.ToArray())

       ' Dimension the target array and copy each element of each source array to it.
       Dim newArray() As Integer = {}
       ' Define the next position to copy to in newArray.
       Dim index = 0
       For Each task In tasks
          Dim n = Task.Result.Length
          ReDim Preserve newArray(newArray.GetUpperBound(0) + n)
          Array.Copy(task.Result, 0, newArray, index, n)
          index += n
       Next 
      Console.WriteLine($"The new array has {newArray.Length} elements.")
   End Sub
End Module
' The example displays the following output:
'     The new array has 40 elements.

Kolekcje jako alternatywa dla tablic

Tablice są najbardziej przydatne do tworzenia i pracy z ustaloną liczbą silnie typizowanych obiektów. Kolekcje zapewniają bardziej elastyczny sposób pracy z grupami obiektów. W przeciwieństwie do tablic, które wymagają jawnej zmiany rozmiaru tablicy za pomocą ReDim instrukcji, kolekcje rosną i zmniejszają się dynamicznie w miarę zmiany potrzeb aplikacji.

Gdy używasz ReDim do zmiany rozmiaru tablicy, program Visual Basic tworzy nową tablicę i zwalnia poprzednią. Wymaga to czasu wykonania. W związku z tym, jeśli liczba elementów, z którymi pracujesz, często się zmienia lub nie możesz przewidzieć maksymalnej liczby potrzebnych elementów, zwykle uzyskasz lepszą wydajność, używając kolekcji.

W przypadku niektórych kolekcji można przypisać klucz do dowolnego obiektu umieszczonego w kolekcji, aby można było szybko pobrać obiekt przy użyciu klucza.

Jeśli kolekcja zawiera elementy tylko jednego typu danych, możesz użyć jednej z klas w System.Collections.Generic przestrzeni nazw. Kolekcja ogólna wymusza bezpieczeństwo typu, aby nie można było do niego dodać żadnego innego typu danych.

Aby uzyskać więcej informacji na temat kolekcji, zobacz Kolekcje.

Termin Definicja
Wymiary tablicy w Visual Basic Objaśnia rangę i wymiary w tablicach.
Jak: zainicjować zmienną tablicową w Visual Basic Opisuje sposób wypełniania tablic wartościami początkowymi.
Jak sortować tablicę w Visual Basic Pokazuje sposób sortowania elementów tablicy alfabetycznie.
Instrukcje: przypisywanie jednej tablicy do innej tablicy Opisuje reguły i kroki przypisywania tablicy do innej zmiennej tablicy.
Rozwiązywanie problemów z tablicami Omówienie niektórych typowych problemów, które pojawiają się podczas pracy z tablicami.

Zobacz także