Массивы в Visual Basic

Массив представляет собой набор значений, логически связанных друг с другом, например, число учеников в каждом классе в школе.

С помощью массива можно ссылаться на эти связанные значения по одному имени и используя номер, называемый индексом или подиндексом, чтобы отличить элементы друг от друга. Отдельные значения, называются элементами массива. Они представляются непрерывной последовательностью от индекса 0 до наибольшего значения индекса.

В отличие от массива, переменная, содержащая одиночное значение, называется скалярной переменной.

Содержание раздела

  • Элементы массива в простом массиве

  • Создание массива

  • Объявление массива

  • Сохранение значений в массиве

  • Заполнение массива начальными значениями

    • Вложенные литералы массива
  • Перебор массива

  • Массивы как возвращаемые значения и параметры

  • Массивы массивов

  • Массивы нулевой длины

  • Размер массива

  • Типы массива и другие типы

  • Коллекции как альтернатива массивам

Элементы массива в простом массиве

В следующем примере объявляется переменная массива для хранения числа учеников в каждом классе школы.

Dim students(6) As Integer

Массив students в предыдущем примере содержит семь элементов. Индексы элементов лежат в диапазоне от 0 до 6. Использовать массив проще, чем объявить семь отдельных переменных.

На следующем рисунке показан массив students. Для каждого элемента массива:

  • Индекс элемента представляет школьный класс (индекс 0 представляет детский сад).

  • Значение, содержащееся в элементе, представляет число учеников в этом классе.

Элементы массива "учеников"

Изображение массива, отображающее количество студентов

В следующем примере показано обращение к первому, второму и последнему элементу массива 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 в предыдущем примере использует один индекс и считается одномерным. Массив, использующий более одного индекса, называется многомерным массивом. Дополнительные сведения далее в этом разделе в разделе Размерность массивов в 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. За именем переменой следуют одна или более пар скобок, показывающие, что это массив, а не скаляр (переменная, содержащая одно значение).

После объявления массива можно определить его размер с помощью Оператор 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. Можно сохранять и извлекать значения массива, ссылаясь на местоположение в массиве с помощью индекса места, приведенного в скобках. Индексы для многомерных массивов разделяются запятыми (,). Для каждого измерения массива требуется один индекс. В следующем примере показаны некоторые операторы, которые сохраняют значения в массивах.

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

В следующем примере показаны некоторые операторы, которые получают значения из массивов.

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)

Заполнение массива начальными значениями

Можно создать массив, содержащий начальный набор значений, с помощью литерала массива. Литерал массива состоит из списка разделенных запятыми значений, заключенных в фигурные скобки ({}).

При создании массива с помощью литерала массива можно либо указать тип массива, либо использовать вывод типа для определения типа массива. В следующем коде показаны обе возможности.

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

При использовании вывода типа тип массива определяется главным типом списка значений, предоставленного для литерала массива. Главный тип — это уникальный тип, до которого могут быть расширены все другие типы литерала массива. Если такой уникальный тип нельзя определить, то главным типом будет тип, до которого можно сузить все другие типы массива. Если ни один из указанных уникальных типов нельзя определить, главным типом будет Object. Например, если список значений для литерала массива содержит значения типов Integer, Long и Double, результирующий массив будет иметь тип Double. Типы Integer и Long расширяются только до типа Double. Поэтому Double является главным типом. Для получения дополнительной информации см. Расширяющие и сужающие преобразования (Visual Basic). Данные правила вывода применимы для вывода типов массивов, которые являются локальными переменными, определенными в элементе класса. Несмотря на то что можно использовать литералы массива при создании переменных уровня класса, нельзя использовать вывод типа на уровне класса. В результате литералы массива, заданные на уровне класса, определяют значения, указанные для литерала массива, как тип Object.

Можно явно задать тип элементов в массиве, созданном с помощью литерала массива. В таком случае значения литерала массива должны расширяться до типа элементов массива. В следующем примере кода создается массив типа Double из списка целых чисел.

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

Вложенные литералы массива

Можно создать многомерный массив с помощью вложенных литералов массива. Вложенные литералы массива должны иметь измерение и число измерений, называемое ранг, соответствующее результирующему массиву. В следующем примере кода создается двухмерный массив целых чисел с помощью литерала массива.

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

В предыдущем примере возникла бы ошибка, если бы число элементов во вложенных литералах массива не совпадало. Ошибка также возникла бы, если бы переменная массива была объявлена явно не двухмерной.

Примечание

Избежать ошибки при указании вложенных литералов массива с различными измерениями можно, заключив внутренние литералы массива в круглые скобки.Скобки требуют принудительного вычисления значения выражения литерала массива, полученные значения используются со внешним литералом массива, как показано в следующем коде.

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

При создании многомерного массива с помощью вложенных литералов массива можно использовать вывод типа. При использовании вывода типа выводимый тип является главным типом для всех значений всех литералов массива какого-либо уровня вложенности. В следующем примере кода создается двухмерный массив типа Double из значений типа Integer и 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, задайте параметр как массив с указанными типом данных и количеством измерений. В вызове процедуры отправьте переменную массива с тем же типом данных и количеством измерений.

В следующем примере функция GetNumbers возвращает Integer(). Этот тип массива — одномерный массив типа 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

В следующем примере функция GetNumbersMultiDim возвращает Integer(,). Этот тип массива — одномерный массив типа 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, таким как Length или Rank, или вызывать функцию Visual Basic, такую как UBound.

  • Требуется сделать соответствующий код проще, избежав необходимости проверки на значение Nothing как особый случай.

  • Код взаимодействует с интерфейсом API, который требует передачи массива нулевой длины в одну или несколько процедур или возвращает массив нулевой длины из одной или нескольких процедур.

Размер массива

Размер массива является произведением длин всех его измерений. Он представляет собой общее число элементов, в данный момент содержащихся в массиве.

В следующем примере показано объявление трехмерного массива:

Dim prices(3, 4, 5) As Long

Общий размер массива в переменной prices составляет (3 + 1) x (4 + 1) x (5 + 1) = 120.

Размер массива можно определить с помощью свойства Length. Длину каждого измерения многомерного массива можно получить с помощью метода GetLength.

Можно изменять размер переменной массива, присваивая ей новый объект массива, или с помощью оператора ReDim.

Существует ряд особенностей, о которых следует помнить при работе с размером массива.

Длина измерения

Индекс каждого измерения начинается с 0, что означает, что его диапазон от 0 до верхней границы. Таким образом, длина данного измерения на 1 больше объявленной верхней границы этого измерения.

Ограничения длины

Длина каждого измерения массива ограничена максимальным значением типа Integer, которое равно (2 ^ 31) - 1. Тем не менее, общий размер массива также ограничен доступной памятью в системе. При попытке инициализировать массив, размер которого превышает объем доступной оперативной памяти, общеязыковая среда выполнения создает исключение OutOfMemoryException.

Размер и размер элемента

Размер массива не зависит от типа его элементов. Размер всегда представляет общее число элементов, а не число байтов, занимаемое массивом при хранении.

Затраты памяти

Небезопасно делать любые предположения относительно способа хранения массива в памяти. Хранение зависит от размерности данных платформы, так один и тот же массив может потреблять больше памяти на 64-разрядных системах, чем на 32-разрядных. В зависимости от конфигурации системы при инициализации массива общеязыковая среда выполнения (CLR) может указывать такие способы хранения, как упаковка элементов максимально близко друг к другу или выравнивание всех элементов по естественным аппаратным границам памяти. Кроме того массив нуждается в хранении служебной информации, и размер этой информации возрастает при каждом добавлении измерения.

Типы массива и другие типы

Каждый массив имеет тип данных, но этот тип отличается от типа данных его элементов. Не существует единого типа данных, подходящего для всех массивов. Вместо этого тип данных массива определяется числом измерений массива, или рангом, и типом данных элементов массива. Две переменные массивов имеют один тип, только если массивы одного ранга и содержат данные одного и того же типа. Длины измерений массива не влияют на тип данных массива.

Каждый массив наследуется от класса 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)))

Коллекции как альтернатива массивам

Массивы удобнее всего использовать для создания и работы с фиксированным числом строго типизированных объектов. Коллекции обеспечивают более гибкий способ для работы с группами объектов. В отличие от массивов, группа объектов в классе может динамически возрастать и сокращаться в соответствии с потребностями приложения.

Если требуется изменить размер массива, необходимо использовать Оператор ReDim (Visual Basic). После этого Visual Basic создает новый массив и освобождает предыдущий массив. Это занимает время выполнения. Таким образом, если число элементов при работе изменяется часто или нельзя предсказать максимальное число необходимых элементов, можно получить большую производительность при использовании коллекции.

При работе с некоторыми коллекциями можно присвоить ключ любому объекту, который необходимо поместить в коллекцию, чтобы можно было быстро получить объект по ключу.

Если коллекция содержит элементы только одного типа данных, можно использовать один из классов в пространстве имен System.Collections.Generic. Универсальная коллекция обеспечивает безопасность типов, так что другие типы данных не могут быть в нее добавлены. При извлечении элемента из универсальной коллекции нет необходимости определять или преобразовывать его тип данных.

Дополнительные сведения о коллекциях см. в разделе Коллекции (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

Объяснение ранга и измерений в массиве.

Практическое руководство. Инициализация переменной массива в Visual Basic

Описывает заполнение массивов начальными значениями.

Практическое руководство. Сортировка массива в Visual Basic

Объяснение, как сортировать элементы массива в алфавитном порядке.

Практическое руководство. Присвоение одного массива другому (Visual Basic)

Описание правил и действий для назначения массива другой переменной массива.

Устранение неполадок, связанных с массивами (Visual Basic)

Рассмотрение некоторых общих проблем, возникающих при работе с массивами.

См. также

Ссылки

Оператор Dim (Visual Basic)

Оператор ReDim (Visual Basic)

Array