Разное

Массивы в бейсике: Массивы — Visual Basic | Microsoft Docs

Содержание

Объявление массивов (VBA) | Microsoft Docs

  • Чтение занимает 2 мин

В этой статье

Массивы объявляются так же, как и другие переменные, при помощи операторов Dim, Static, Private или PublicArrays are declared the same way as other variables, by using the Dim, Static, Private, or Public statements. Отличие скалярных переменных (которые не являются массивами) от переменных массивов заключается в том, что для массива, как правило, необходимо указывать размер.The difference between scalar variables (those that aren’t arrays) and array variables is that you generally must specify the size of the array. Массив с указанным размером является массивом фиксированного размера.An array whose size is specified is a fixed-size array. Массив, размер которого можно изменить во время выполнения программы, является динамическим массивом.An array whose size can be changed while a program is running is a dynamic array.

Индексация массива от 0 или 1 зависит от оператора Option Base.Whether an array is indexed from 0 or 1 depends on the setting of the Option Base statement. Если не указано Option Base 1, все индексы массива будут начинается с нуля.If Option Base 1 is not specified, all array indexes begin at zero.

Объявление статического массиваDeclare a fixed array

В приведенном ниже примере кода массив фиксированного размера объявлен массивом целых переменных (Integer) с 11 строками и 11 столбцами:In the following line of code, a fixed-size array is declared as an Integer array having 11 rows and 11 columns:

Dim MyArray(10, 10) As Integer 

Первый аргумент определяет количество строк, второй — столбцов.The first argument represents the rows; the second argument represents the columns.

Как и в случае объявления любой другой переменной, если для объявленного массива не указать тип данных, его элементам будет присвоен тип данных Variant.As with any other variable declaration, unless you specify a data type for the array, the data type of the elements in a declared array is Variant. Каждый числовой элемент Variant массива использует 16 байтов.Each numeric Variant element of the array uses 16 bytes. Каждый строчный элемент Variant использует 22 байта.Each string Variant element uses 22 bytes. Чтобы написать как можно более компактный код, четко объявите для своих массивов тип данных, отличный от Variant.To write code that is as compact as possible, explicitly declare your arrays to be of a data type other than

Variant.

В приведенном ниже примере кода сравниваются размеры нескольких массивов.The following lines of code compare the size of several arrays.

' Integer array uses 22 bytes (11 elements * 2 bytes). 
ReDim MyIntegerArray(10) As Integer 
 
' Double-precision array uses 88 bytes (11 elements * 8 bytes). 
ReDim MyDoubleArray(10) As Double 
 
' Variant array uses at least 176 bytes (11 elements * 16 bytes). 
ReDim MyVariantArray(10) 
 
' Integer array uses 100 * 100 * 2 bytes (20,000 bytes). 
ReDim MyIntegerArray (99, 99) As Integer 
 
' Double-precision array uses 100 * 100 * 8 bytes (80,000 bytes). 
ReDim MyDoubleArray (99, 99) As Double 
 
' Variant array uses at least 160,000 bytes (100 * 100 * 16 bytes). 
ReDim MyVariantArray(99, 99) 

Максимальный размер массивов зависит от операционной системы и доступного объема памяти.The maximum size of an array varies, based on your operating system and how much memory is available. Использование массивов, размер которых превышает объем доступной оперативной памяти вашего компьютера, приводит к снижению скорости, поскольку системе необходимо выполнять запись данных и чтение с диска.Using an array that exceeds the amount of RAM available on your system is slower because the data must be read from and written to disk.

Объявление динамического массиваDeclare a dynamic array

Объявив динамический массив, вы сможете менять его размер во время выполнения кода.By declaring a dynamic array, you can size the array while the code is running. Используйте операторы Static, Dim, Private или Public, чтобы объявить массив, не указывая значение в скобках, как показано в следующем примере:Use a Static, Dim, Private, or Public statement to declare an array, leaving the parentheses empty, as shown in the following example.

Dim sngArray() As Single 

Примечание

Вы можете неявно объявить массив в процедуре при помощи оператора ReDim.You can use the ReDim statement to declare an array implicitly within a procedure. Будьте внимательны и вводите имя массива без ошибок при использовании оператора ReDim.Be careful not to misspell the name of the array when you use the ReDim statement. Даже если в модуль включен оператор Option Explicit, будет создан второй массив.Even if the Option Explicit statement is included in the module, a second array will be created.

В процедуре внутри области массива используйте оператор ReDim, чтобы изменить количество измерений, задать количество элементов и определить нижнюю и верхнюю границы каждого измерения.In a procedure within the array’s scope, use the ReDim statement to change the number of dimensions, to define the number of elements, and to define the upper and lower bounds for each dimension. Вы можете менять динамический массив при помощи оператора

ReDim в любое время.You can use the ReDim statement to change the dynamic array as often as necessary. Однако значения внутри массива при этом не сохраняются.However, each time you do this, the existing values in the array are lost. Используйте ReDim Preserve для расширения массива, сохраняя при этом текущие значения.Use ReDim Preserve to expand an array while preserving existing values in the array.

Например, приведенный ниже оператор увеличивает массив на 10 элементов, сохраняя при этом текущие значения исходных элементов.For example, the following statement enlarges the array by 10 elements without losing the current values of the original elements.

ReDim Preserve varArray(UBound(varArray) + 10) 

Примечание

При использовании ключевого слова Preserve внутри динамического массива можно менять только верхнюю границу последнего измерения; изменить количество измерений нельзя.When you use the Preserve keyword with a dynamic array, you can change only the upper bound of the last dimension, but you can’t change the number of dimensions.

См. такжеSee also

Поддержка и обратная связьSupport and feedback

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи?Have questions or feedback about Office VBA or this documentation? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.

Массивы в VBA — Макросы и программы VBA — Excel — Каталог статей

Содержание:

Зачем нужны массивы

Массивы очень упрощают процесс программирования. Без них практически невозможно написать универсальную программу. Например, представьте себе, что вы манипулируете информацией о квартирах жилого дома. Вы объявляете переменные K1 — для первой квартиры, K2 — для второй и так далее. K1=54 будет означать, что площадь первой квартиры 54 кв.м., К2=72 и т.д. Теперь представим, что нам надо подсчитать общую площадь всех квартир в доме. Очевидно, что это что-то типа Total_S = K1+K2+…+Kn. В одном доме у нас 36 квартир, а в другом 144. Представляете бредовость процесса подобного программирования? Если в первом случае я должен буду использовать 36 отдельных переменных для вычисления общей площади, то для второго дома уже 144. Очень быстро вы придёте к мысли, что вам нужна переменная, состоящая из нумерованных ячеек. Тогда обретают смысл все те операторы циклов, входящие в состав любого языка программирования. Но об этом чуть позже…

▲ вверх

Что такое массив

Массив — переменная, состоящая из некоторого количества однотипных элементов. У массива, как и у любой другой переменной, есть имя. А доступ к конкретному элементу массива осуществляется через указание в скобках после имени его индекса. Например, A(5) означает, что я обращаюсь к элементу с индексом 5 массива, имеющего имя A.

▲ вверх

Типы массивов

Массивы в VBA и во многих других языках программирования делятся на 2 класса:

  • Фиксированные массивы. Такие массивы состоят из заранее известного количества элементов. Это количество определяется во время объявления массива и уже не может быть изменено в процессе его жизненного цикла. Вы, конечно же, сможете использовать меньшее количество элементов, но не существует способа увеличить количество элементов сверх объявленного.

  • Динамические массивы. Эти массивы можно «переобъявлять» в процессе жизненного цикла. То есть мы можем управлять количеством элементов динамических масивов в зависимости от наших потребностей. Это очень удобно, так как в подавляющем большинстве случаев программист не может заранее знать, с каким объёмом данных он столкнётся. Если вы собираетесь писать более-менее универсальные программы, то этот тип массивов определенно стоит изучить.

▲ вверх

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


Объявление фиксированных массивов

Рекомендация: при объявлении массивов VBA я советую вам давать всем именам префикс «arr». Я сторонник венгерской нотации.

Как мы видим, тут объявлено 2 одномерных массива arrTemp и arrTest. Одномерные массивы в программировании также часто называют векторами. Типом элементов первого массива является Long, второго массива — String. В этом типе синтаксиса в скобках указан максимальный индекс (верхняя граница ) элемента массива. А что насчёт минимального индекса (нижней границы) массива? По-умолчанию минимальным индексом является ноль. В данном случае стандартное поведение интерпретатора языка VBA можно изменить при помощи оператора option base {0|1}. Option base 1 заставляет VBA считать нижней границей массива — единицу, а не ноль.

Таким образом, по-умолчанию массив arrTemp имеет 11 элементов — от 0 до 10. Но, если в начало модуля, в котором этот массив объявляется, вставить оператор Option Base 1, то массив arrTemp будет иметь 10 элементов — от 1 до 10.

Помимо вышеуказанного вы вправе использовать следующий синтаксис, который НЕ зависит от option base {0|1}:

таким образом вы в явном виде указываете и нижнюю, и верхнюю границы. Как видите, нижняя граница совершенно не обязательно должна начинаться с 0 или 1. Более того, индексы границ могут принимать и отрицательные значения, главное чтобы нижняя была меньше верхней.

Помимо одномерных массивов, можно объявлять и массивы с размерностью больше единицы.

arrMulti — двумерный массив, а arrData3 — трёхмерный. Первый содержит 11*31=341 элемент, второй — 2*3*10=60 элементов. Теоретически допускается объявлять до 60 размерностей массива.

Какие типы данных могут стать элементами массива? Тут всё, как в шутке про фамилию еврея, — абсолютно любой тип данных годится на роль элемента массива, включая объектные типы, User Data Type, другие массивы (через тип Variant). Если вы не указываете при объявлении тип данных массива, то предполагается, что этим типом является тип Variant.

▲ вверх

Объявление динамических массивов

Динамические массивы объявляться так:

Однако, использовать их после такого объявления пока ещё нельзя. Необходимо выделить память под массив. Особенность работы с динамическим массивом как раз состоит в том, что программист отвечает за его своевременное расширение (усечение) в памяти. Для этого существует специальный оператор, который имеет следующий синтаксис:

    ReDim [Preserve] varname(subscripts) [As Type]

Например:

После этого оператора, вы можете использовать элементы массива arrOpen с 0-го по 5-й. Всё, что мы говорили про оператор option base и нижнюю границу, верно и для динамических массивов. Предположим, что вы сохранили информацию в элементах 0-5 и у вас поспела новая порция информации для элементов 6-11. Чтобы разместить в данном массиве новые элементы и не потерять старые, вы должны сделать следующее:

то есть мы тут увеличиваем верхнюю границу массива и используем ключевое слово Preserve, чтобы во время этой операции не потерять текущее содержимое arrOpen, так как в противном случае (без слова Preserve) массив будет расширен, а память заполнена нулями. Вы также вправе вообще не декларировать массив оператором Dim, а сделать это впервые через ReDim и там же указать лип элементов. Но, если вы в первом ReDim (или Dim) указали определенный тип элементов, то в последующих операторах ReDim этот тип переопределён быть не может — возникнет ошибка на этапе компиляции проекта.

▲ вверх

Изменение элементов массива

Пора бы нам уже научиться пользоваться нашими массивами — то есть записывать информацию в их элементы и считывать её оттуда. Это довольно просто:

Как и с обычными переменными запись информации в элемент массива происходит через оператор присваивания (=), но указанием индекса элемента массива.

▲ вверх

Чтение элементов массива

▲ вверх

Определение границ массива

В подпрограммах часто приходится иметь дело с массивами, которые переданы вам в качестве параметра (как это сделать показано ниже), поэтому в этом случае очень актуален вопрос определения нижней и верхней границ индекса массива. Для этого в языке предусмотрены 2 функции: LBound и UBound. Первая возвращает нижнюю границу индекса, вторая — верхнюю.

    LBound( array [, dimension])
    UBound( array [, dimension])

Для одномерных массивов параметр dimension можно не указывать. Для многомерных массивов его указывать необходимо. Кстати, это означает, что, если вы точно не знаете, с каким массивом имеете дело, но необходимо узнать его первую размерность, то лучше использовать вариант UBound(arrTemp,1), а не UBound(arrTemp), так как последний вариант вызовет ошибку, если массив окажется многомерным.

Если вы ошибётесь с указанием правильного индекса массива, то возникнет ошибка периода исполнения с кодом 9. Эта же ошибка возникнет, если вы в функции LBound / UBound укажете несуществующую размерность массива (например, 3 для двумерного массива).

▲ вверх

Перебор элементов массива

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

Наиболее удобный оператор цикла для перебора элементов массива — это безусловно For … Next.

так же есть способ не заботиться об определении нижней и верхней границ, если алгоритм не требует от нас знания текущего индекса массива:

Вы, конечно, можете перебирать массив и в других типах циклов Do … Loop, но, право, смысла и удобства в этом не много. По крайней мере я не сталкивался, кажется, с ситуациями, когда для перебора массива цикл For не подошёл.

▲ вверх

Передача массивов в подпрограммы

Массивы удобнее всего передавать в подпрограммы в виде параметра типа Variant.

Обратите внимание, что функции GetResult в качестве параметра передаются массивы. При чём, в первом случае это массив с типом элементов Long, а во втором — String. За счёт того, что внутри функции используются переменные типа Variant, то сначала функция нам возвращает сумму элементов массива arrIntegers, а во втором результат сложения (конкатенации) строк массива arrStrings. Кроме того, параметр parArray не описан как массив (parArray As Variant), но мы внутри функции GetResult ведём себя с ним, как с массивом (For Each Element In parArray)! Это возможно, так как переменные типа Variant умеют определять, что им присваивается и вести себя далее в соответствии с тем, что они содержат. Если переменной parArray присвоили массив (через вызов функции — строки 17 и 18), то она себя будет вести как массив.

▲ вверх

Массив с элементами типа массив

Продемонстрируем, как можно хранить в качестве элементов массива другие массивы.

Результат отладочной печати:

▲ вверх

Функция Array

Данная функция полезна для создания справочных массивов. Она возвращает переменную типа Variant, содержащую одномерный массив с типом элементов Variant.

    Array( arglist )

Вызов функции без параметров приведёт к возврату массива нулевой длинны. При этом будет наблюдаться интересный эффект LBound вернёт вам 0, а UBound вернёт -1, то есть верхняя граница окажется меньше нижней границы.

▲ вверх

Функция Split

Split возвращает одномерный массив, содержащий подстроки, из строкового выражении с учётом указанного разделителя

    Split(expression[, delimiter[, limit[, compare]]])
  • expression — строковое выражение, содержащая подстроки и разделители. Обязательный параметр.

  • delimiter — текстовый разделитель. Необязательный параметр. Если опущен, то предполагается, что разделителем является символ пробела.

  • limit — количество подстрок, которое необходимо вернуть. -1 или отсутствие параметра означает, что вернуть надо все подстроки.

  • compare — константа, указывающая тип сравнения для символов разделителей. 1 — текстовое сравнение (без учёта регистра), 0 — бинарное сравнение (с учётом регистра).

Результат выглядит так:

Если вы в качестве разделителя укажете пустую строку, то на выходе получите массив, состоящий из одного элемента. Кстати, split всегда возвращает массив с нулевой нижней границей вне всякой зависимости от наличия option base 1.

▲ вверх

Нюансы работы с динамическими массивами


Неинициализированный массив

У динамического массива есть такое промежуточное состояние, когда он уже объявлен, но ещё не содержит никаких элементов.

То есть у переменной динамического массива есть такое состояние, когда мы не можем воспользоваться вспомогательными функциями LBound / UBound для определения его (массива) статуса. Это особенно надо учитывать, когда вы пишите подпрограммы, работающие с массивами. Прежде чем работать (перебирать) массив необходимо убедиться, что он проинициализирован, в противном случае программа вылетит с ошибкой 9.

Для этого я предлагаю пользоваться функцией подобной нижеописанной IsNotEmptyArray:

▲ вверх

Расширение массива

Как правило, расширять динамический массив приходится в цикле. Возможны 2 стратегии: расширение на 1 элемент, как только в этом есть необходимость (назовём это эластичным расширением), и расширение авансом, когда вы увеличиваете верхнюю границу скачками, скажем сразу на 100 элементов. Реализовав оба варианта, я для себя сделал вывод, что авансовое расширение получилось и компактнее, и работает быстрее, так как операция расширения, вообще говоря, затратна и, чем реже вызывается, тем лучше.

Результат:

Авансовый метод вышел даже компактнее

▲ вверх

Удаление массива

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

▲ вверх

Получение массива на основе диапазона Excel

Самый эффективный по скорости способ получить содержимое диапазона Excel для манипулирования в VBA — это скопировать его в массив с элементами Variant. Делается так:

Даже, если вы передаёте в массив столбец или строку, получаемый массив всегда будет иметь 2 измерения. Измерение 1 отвечает за строки, измерение 2 — за столбцы. То есть ячейка C5 будет в элементе arrTemp(5,3). Нижняя граница таких массивов всегда будет начинаться с единицы.

▲ вверх

Дополнительные источники

В качестве источника дополнительной информации по массивам я могу порекомендовать замечательный, исчерпывающий ресурс Чарльза Пирсона (Charles H. Pearson). Его сайт следует штудировать всем, кто серьёзно осваивает VBA. Конкретно по массивам там огромное количество готовых подпрограмм для работы с ними, исходные коды, снабженные подробнейшими комментариями, продвинутые объяснения для копающих в глубину. Без преувеличения великолепный ресурс!

▲ вверх

Читайте также:

Массивы в VBA — Макросы и программы VBA — Excel — Каталог статей

Содержание:

Зачем нужны массивы

Массивы очень упрощают процесс программирования. Без них практически невозможно написать универсальную программу. Например, представьте себе, что вы манипулируете информацией о квартирах жилого дома. Вы объявляете переменные K1 — для первой квартиры, K2 — для второй и так далее. K1=54 будет означать, что площадь первой квартиры 54 кв.м., К2=72 и т.д. Теперь представим, что нам надо подсчитать общую площадь всех квартир в доме. Очевидно, что это что-то типа Total_S = K1+K2+…+Kn. В одном доме у нас 36 квартир, а в другом 144. Представляете бредовость процесса подобного программирования? Если в первом случае я должен буду использовать 36 отдельных переменных для вычисления общей площади, то для второго дома уже 144. Очень быстро вы придёте к мысли, что вам нужна переменная, состоящая из нумерованных ячеек. Тогда обретают смысл все те операторы циклов, входящие в состав любого языка программирования. Но об этом чуть позже…

▲ вверх

Что такое массив

Массив — переменная, состоящая из некоторого количества однотипных элементов. У массива, как и у любой другой переменной, есть имя. А доступ к конкретному элементу массива осуществляется через указание в скобках после имени его индекса. Например, A(5) означает, что я обращаюсь к элементу с индексом 5 массива, имеющего имя A.

▲ вверх

Типы массивов

Массивы в VBA и во многих других языках программирования делятся на 2 класса:

  • Фиксированные массивы. Такие массивы состоят из заранее известного количества элементов. Это количество определяется во время объявления массива и уже не может быть изменено в процессе его жизненного цикла. Вы, конечно же, сможете использовать меньшее количество элементов, но не существует способа увеличить количество элементов сверх объявленного.

  • Динамические массивы. Эти массивы можно «переобъявлять» в процессе жизненного цикла. То есть мы можем управлять количеством элементов динамических масивов в зависимости от наших потребностей. Это очень удобно, так как в подавляющем большинстве случаев программист не может заранее знать, с каким объёмом данных он столкнётся. Если вы собираетесь писать более-менее универсальные программы, то этот тип массивов определенно стоит изучить.

▲ вверх

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


Объявление фиксированных массивов

Рекомендация: при объявлении массивов VBA я советую вам давать всем именам префикс «arr». Я сторонник венгерской нотации.

Как мы видим, тут объявлено 2 одномерных массива arrTemp и arrTest. Одномерные массивы в программировании также часто называют векторами. Типом элементов первого массива является Long, второго массива — String. В этом типе синтаксиса в скобках указан максимальный индекс (верхняя граница ) элемента массива. А что насчёт минимального индекса (нижней границы) массива? По-умолчанию минимальным индексом является ноль. В данном случае стандартное поведение интерпретатора языка VBA можно изменить при помощи оператора option base {0|1}. Option base 1 заставляет VBA считать нижней границей массива — единицу, а не ноль.

Таким образом, по-умолчанию массив arrTemp имеет 11 элементов — от 0 до 10. Но, если в начало модуля, в котором этот массив объявляется, вставить оператор Option Base 1, то массив arrTemp будет иметь 10 элементов — от 1 до 10.

Помимо вышеуказанного вы вправе использовать следующий синтаксис, который НЕ зависит от option base {0|1}:

таким образом вы в явном виде указываете и нижнюю, и верхнюю границы. Как видите, нижняя граница совершенно не обязательно должна начинаться с 0 или 1. Более того, индексы границ могут принимать и отрицательные значения, главное чтобы нижняя была меньше верхней.

Помимо одномерных массивов, можно объявлять и массивы с размерностью больше единицы.

arrMulti — двумерный массив, а arrData3 — трёхмерный. Первый содержит 11*31=341 элемент, второй — 2*3*10=60 элементов. Теоретически допускается объявлять до 60 размерностей массива.

Какие типы данных могут стать элементами массива? Тут всё, как в шутке про фамилию еврея, — абсолютно любой тип данных годится на роль элемента массива, включая объектные типы, User Data Type, другие массивы (через тип Variant). Если вы не указываете при объявлении тип данных массива, то предполагается, что этим типом является тип Variant.

▲ вверх

Объявление динамических массивов

Динамические массивы объявляться так:

Однако, использовать их после такого объявления пока ещё нельзя. Необходимо выделить память под массив. Особенность работы с динамическим массивом как раз состоит в том, что программист отвечает за его своевременное расширение (усечение) в памяти. Для этого существует специальный оператор, который имеет следующий синтаксис:

    ReDim [Preserve] varname(subscripts) [As Type]

Например:

После этого оператора, вы можете использовать элементы массива arrOpen с 0-го по 5-й. Всё, что мы говорили про оператор option base и нижнюю границу, верно и для динамических массивов. Предположим, что вы сохранили информацию в элементах 0-5 и у вас поспела новая порция информации для элементов 6-11. Чтобы разместить в данном массиве новые элементы и не потерять старые, вы должны сделать следующее:

то есть мы тут увеличиваем верхнюю границу массива и используем ключевое слово Preserve, чтобы во время этой операции не потерять текущее содержимое arrOpen, так как в противном случае (без слова Preserve) массив будет расширен, а память заполнена нулями. Вы также вправе вообще не декларировать массив оператором Dim, а сделать это впервые через ReDim и там же указать лип элементов. Но, если вы в первом ReDim (или Dim) указали определенный тип элементов, то в последующих операторах ReDim этот тип переопределён быть не может — возникнет ошибка на этапе компиляции проекта.

▲ вверх

Изменение элементов массива

Пора бы нам уже научиться пользоваться нашими массивами — то есть записывать информацию в их элементы и считывать её оттуда. Это довольно просто:

Как и с обычными переменными запись информации в элемент массива происходит через оператор присваивания (=), но указанием индекса элемента массива.

▲ вверх

Чтение элементов массива

▲ вверх

Определение границ массива

В подпрограммах часто приходится иметь дело с массивами, которые переданы вам в качестве параметра (как это сделать показано ниже), поэтому в этом случае очень актуален вопрос определения нижней и верхней границ индекса массива. Для этого в языке предусмотрены 2 функции: LBound и UBound. Первая возвращает нижнюю границу индекса, вторая — верхнюю.

    LBound( array [, dimension])
    UBound( array [, dimension])

Для одномерных массивов параметр dimension можно не указывать. Для многомерных массивов его указывать необходимо. Кстати, это означает, что, если вы точно не знаете, с каким массивом имеете дело, но необходимо узнать его первую размерность, то лучше использовать вариант UBound(arrTemp,1), а не UBound(arrTemp), так как последний вариант вызовет ошибку, если массив окажется многомерным.

Если вы ошибётесь с указанием правильного индекса массива, то возникнет ошибка периода исполнения с кодом 9. Эта же ошибка возникнет, если вы в функции LBound / UBound укажете несуществующую размерность массива (например, 3 для двумерного массива).

▲ вверх

Перебор элементов массива

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

Наиболее удобный оператор цикла для перебора элементов массива — это безусловно For … Next.

так же есть способ не заботиться об определении нижней и верхней границ, если алгоритм не требует от нас знания текущего индекса массива:

Вы, конечно, можете перебирать массив и в других типах циклов Do … Loop, но, право, смысла и удобства в этом не много. По крайней мере я не сталкивался, кажется, с ситуациями, когда для перебора массива цикл For не подошёл.

▲ вверх

Передача массивов в подпрограммы

Массивы удобнее всего передавать в подпрограммы в виде параметра типа Variant.

Обратите внимание, что функции GetResult в качестве параметра передаются массивы. При чём, в первом случае это массив с типом элементов Long, а во втором — String. За счёт того, что внутри функции используются переменные типа Variant, то сначала функция нам возвращает сумму элементов массива arrIntegers, а во втором результат сложения (конкатенации) строк массива arrStrings. Кроме того, параметр parArray не описан как массив (parArray As Variant), но мы внутри функции GetResult ведём себя с ним, как с массивом (For Each Element In parArray)! Это возможно, так как переменные типа Variant умеют определять, что им присваивается и вести себя далее в соответствии с тем, что они содержат. Если переменной parArray присвоили массив (через вызов функции — строки 17 и 18), то она себя будет вести как массив.

▲ вверх

Массив с элементами типа массив

Продемонстрируем, как можно хранить в качестве элементов массива другие массивы.

Результат отладочной печати:

▲ вверх

Функция Array

Данная функция полезна для создания справочных массивов. Она возвращает переменную типа Variant, содержащую одномерный массив с типом элементов Variant.

    Array( arglist )

Вызов функции без параметров приведёт к возврату массива нулевой длинны. При этом будет наблюдаться интересный эффект LBound вернёт вам 0, а UBound вернёт -1, то есть верхняя граница окажется меньше нижней границы.

▲ вверх

Функция Split

Split возвращает одномерный массив, содержащий подстроки, из строкового выражении с учётом указанного разделителя

    Split(expression[, delimiter[, limit[, compare]]])
  • expression — строковое выражение, содержащая подстроки и разделители. Обязательный параметр.

  • delimiter — текстовый разделитель. Необязательный параметр. Если опущен, то предполагается, что разделителем является символ пробела.

  • limit — количество подстрок, которое необходимо вернуть. -1 или отсутствие параметра означает, что вернуть надо все подстроки.

  • compare — константа, указывающая тип сравнения для символов разделителей. 1 — текстовое сравнение (без учёта регистра), 0 — бинарное сравнение (с учётом регистра).

Результат выглядит так:

Если вы в качестве разделителя укажете пустую строку, то на выходе получите массив, состоящий из одного элемента. Кстати, split всегда возвращает массив с нулевой нижней границей вне всякой зависимости от наличия option base 1.

▲ вверх

Нюансы работы с динамическими массивами


Неинициализированный массив

У динамического массива есть такое промежуточное состояние, когда он уже объявлен, но ещё не содержит никаких элементов.

То есть у переменной динамического массива есть такое состояние, когда мы не можем воспользоваться вспомогательными функциями LBound / UBound для определения его (массива) статуса. Это особенно надо учитывать, когда вы пишите подпрограммы, работающие с массивами. Прежде чем работать (перебирать) массив необходимо убедиться, что он проинициализирован, в противном случае программа вылетит с ошибкой 9.

Для этого я предлагаю пользоваться функцией подобной нижеописанной IsNotEmptyArray:

▲ вверх

Расширение массива

Как правило, расширять динамический массив приходится в цикле. Возможны 2 стратегии: расширение на 1 элемент, как только в этом есть необходимость (назовём это эластичным расширением), и расширение авансом, когда вы увеличиваете верхнюю границу скачками, скажем сразу на 100 элементов. Реализовав оба варианта, я для себя сделал вывод, что авансовое расширение получилось и компактнее, и работает быстрее, так как операция расширения, вообще говоря, затратна и, чем реже вызывается, тем лучше.

Результат:

Авансовый метод вышел даже компактнее

▲ вверх

Удаление массива

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

▲ вверх

Получение массива на основе диапазона Excel

Самый эффективный по скорости способ получить содержимое диапазона Excel для манипулирования в VBA — это скопировать его в массив с элементами Variant. Делается так:

Даже, если вы передаёте в массив столбец или строку, получаемый массив всегда будет иметь 2 измерения. Измерение 1 отвечает за строки, измерение 2 — за столбцы. То есть ячейка C5 будет в элементе arrTemp(5,3). Нижняя граница таких массивов всегда будет начинаться с единицы.

▲ вверх

Дополнительные источники

В качестве источника дополнительной информации по массивам я могу порекомендовать замечательный, исчерпывающий ресурс Чарльза Пирсона (Charles H. Pearson). Его сайт следует штудировать всем, кто серьёзно осваивает VBA. Конкретно по массивам там огромное количество готовых подпрограмм для работы с ними, исходные коды, снабженные подробнейшими комментариями, продвинутые объяснения для копающих в глубину. Без преувеличения великолепный ресурс!

▲ вверх

Читайте также:

Массивы в VBA — Макросы и программы VBA — Excel — Каталог статей

Содержание:

Зачем нужны массивы

Массивы очень упрощают процесс программирования. Без них практически невозможно написать универсальную программу. Например, представьте себе, что вы манипулируете информацией о квартирах жилого дома. Вы объявляете переменные K1 — для первой квартиры, K2 — для второй и так далее. K1=54 будет означать, что площадь первой квартиры 54 кв.м., К2=72 и т.д. Теперь представим, что нам надо подсчитать общую площадь всех квартир в доме. Очевидно, что это что-то типа Total_S = K1+K2+…+Kn. В одном доме у нас 36 квартир, а в другом 144. Представляете бредовость процесса подобного программирования? Если в первом случае я должен буду использовать 36 отдельных переменных для вычисления общей площади, то для второго дома уже 144. Очень быстро вы придёте к мысли, что вам нужна переменная, состоящая из нумерованных ячеек. Тогда обретают смысл все те операторы циклов, входящие в состав любого языка программирования. Но об этом чуть позже…

▲ вверх

Что такое массив

Массив — переменная, состоящая из некоторого количества однотипных элементов. У массива, как и у любой другой переменной, есть имя. А доступ к конкретному элементу массива осуществляется через указание в скобках после имени его индекса. Например, A(5) означает, что я обращаюсь к элементу с индексом 5 массива, имеющего имя A.

▲ вверх

Типы массивов

Массивы в VBA и во многих других языках программирования делятся на 2 класса:

  • Фиксированные массивы. Такие массивы состоят из заранее известного количества элементов. Это количество определяется во время объявления массива и уже не может быть изменено в процессе его жизненного цикла. Вы, конечно же, сможете использовать меньшее количество элементов, но не существует способа увеличить количество элементов сверх объявленного.

  • Динамические массивы. Эти массивы можно «переобъявлять» в процессе жизненного цикла. То есть мы можем управлять количеством элементов динамических масивов в зависимости от наших потребностей. Это очень удобно, так как в подавляющем большинстве случаев программист не может заранее знать, с каким объёмом данных он столкнётся. Если вы собираетесь писать более-менее универсальные программы, то этот тип массивов определенно стоит изучить.

▲ вверх

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


Объявление фиксированных массивов

Рекомендация: при объявлении массивов VBA я советую вам давать всем именам префикс «arr». Я сторонник венгерской нотации.

Как мы видим, тут объявлено 2 одномерных массива arrTemp и arrTest. Одномерные массивы в программировании также часто называют векторами. Типом элементов первого массива является Long, второго массива — String. В этом типе синтаксиса в скобках указан максимальный индекс (верхняя граница ) элемента массива. А что насчёт минимального индекса (нижней границы) массива? По-умолчанию минимальным индексом является ноль. В данном случае стандартное поведение интерпретатора языка VBA можно изменить при помощи оператора option base {0|1}. Option base 1 заставляет VBA считать нижней границей массива — единицу, а не ноль.

Таким образом, по-умолчанию массив arrTemp имеет 11 элементов — от 0 до 10. Но, если в начало модуля, в котором этот массив объявляется, вставить оператор Option Base 1, то массив arrTemp будет иметь 10 элементов — от 1 до 10.

Помимо вышеуказанного вы вправе использовать следующий синтаксис, который НЕ зависит от option base {0|1}:

таким образом вы в явном виде указываете и нижнюю, и верхнюю границы. Как видите, нижняя граница совершенно не обязательно должна начинаться с 0 или 1. Более того, индексы границ могут принимать и отрицательные значения, главное чтобы нижняя была меньше верхней.

Помимо одномерных массивов, можно объявлять и массивы с размерностью больше единицы.

arrMulti — двумерный массив, а arrData3 — трёхмерный. Первый содержит 11*31=341 элемент, второй — 2*3*10=60 элементов. Теоретически допускается объявлять до 60 размерностей массива.

Какие типы данных могут стать элементами массива? Тут всё, как в шутке про фамилию еврея, — абсолютно любой тип данных годится на роль элемента массива, включая объектные типы, User Data Type, другие массивы (через тип Variant). Если вы не указываете при объявлении тип данных массива, то предполагается, что этим типом является тип Variant.

▲ вверх

Объявление динамических массивов

Динамические массивы объявляться так:

Однако, использовать их после такого объявления пока ещё нельзя. Необходимо выделить память под массив. Особенность работы с динамическим массивом как раз состоит в том, что программист отвечает за его своевременное расширение (усечение) в памяти. Для этого существует специальный оператор, который имеет следующий синтаксис:

    ReDim [Preserve] varname(subscripts) [As Type]

Например:

После этого оператора, вы можете использовать элементы массива arrOpen с 0-го по 5-й. Всё, что мы говорили про оператор option base и нижнюю границу, верно и для динамических массивов. Предположим, что вы сохранили информацию в элементах 0-5 и у вас поспела новая порция информации для элементов 6-11. Чтобы разместить в данном массиве новые элементы и не потерять старые, вы должны сделать следующее:

то есть мы тут увеличиваем верхнюю границу массива и используем ключевое слово Preserve, чтобы во время этой операции не потерять текущее содержимое arrOpen, так как в противном случае (без слова Preserve) массив будет расширен, а память заполнена нулями. Вы также вправе вообще не декларировать массив оператором Dim, а сделать это впервые через ReDim и там же указать лип элементов. Но, если вы в первом ReDim (или Dim) указали определенный тип элементов, то в последующих операторах ReDim этот тип переопределён быть не может — возникнет ошибка на этапе компиляции проекта.

▲ вверх

Изменение элементов массива

Пора бы нам уже научиться пользоваться нашими массивами — то есть записывать информацию в их элементы и считывать её оттуда. Это довольно просто:

Как и с обычными переменными запись информации в элемент массива происходит через оператор присваивания (=), но указанием индекса элемента массива.

▲ вверх

Чтение элементов массива

▲ вверх

Определение границ массива

В подпрограммах часто приходится иметь дело с массивами, которые переданы вам в качестве параметра (как это сделать показано ниже), поэтому в этом случае очень актуален вопрос определения нижней и верхней границ индекса массива. Для этого в языке предусмотрены 2 функции: LBound и UBound. Первая возвращает нижнюю границу индекса, вторая — верхнюю.

    LBound( array [, dimension])
    UBound( array [, dimension])

Для одномерных массивов параметр dimension можно не указывать. Для многомерных массивов его указывать необходимо. Кстати, это означает, что, если вы точно не знаете, с каким массивом имеете дело, но необходимо узнать его первую размерность, то лучше использовать вариант UBound(arrTemp,1), а не UBound(arrTemp), так как последний вариант вызовет ошибку, если массив окажется многомерным.

Если вы ошибётесь с указанием правильного индекса массива, то возникнет ошибка периода исполнения с кодом 9. Эта же ошибка возникнет, если вы в функции LBound / UBound укажете несуществующую размерность массива (например, 3 для двумерного массива).

▲ вверх

Перебор элементов массива

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

Наиболее удобный оператор цикла для перебора элементов массива — это безусловно For … Next.

так же есть способ не заботиться об определении нижней и верхней границ, если алгоритм не требует от нас знания текущего индекса массива:

Вы, конечно, можете перебирать массив и в других типах циклов Do … Loop, но, право, смысла и удобства в этом не много. По крайней мере я не сталкивался, кажется, с ситуациями, когда для перебора массива цикл For не подошёл.

▲ вверх

Передача массивов в подпрограммы

Массивы удобнее всего передавать в подпрограммы в виде параметра типа Variant.

Обратите внимание, что функции GetResult в качестве параметра передаются массивы. При чём, в первом случае это массив с типом элементов Long, а во втором — String. За счёт того, что внутри функции используются переменные типа Variant, то сначала функция нам возвращает сумму элементов массива arrIntegers, а во втором результат сложения (конкатенации) строк массива arrStrings. Кроме того, параметр parArray не описан как массив (parArray As Variant), но мы внутри функции GetResult ведём себя с ним, как с массивом (For Each Element In parArray)! Это возможно, так как переменные типа Variant умеют определять, что им присваивается и вести себя далее в соответствии с тем, что они содержат. Если переменной parArray присвоили массив (через вызов функции — строки 17 и 18), то она себя будет вести как массив.

▲ вверх

Массив с элементами типа массив

Продемонстрируем, как можно хранить в качестве элементов массива другие массивы.

Результат отладочной печати:

▲ вверх

Функция Array

Данная функция полезна для создания справочных массивов. Она возвращает переменную типа Variant, содержащую одномерный массив с типом элементов Variant.

    Array( arglist )

Вызов функции без параметров приведёт к возврату массива нулевой длинны. При этом будет наблюдаться интересный эффект LBound вернёт вам 0, а UBound вернёт -1, то есть верхняя граница окажется меньше нижней границы.

▲ вверх

Функция Split

Split возвращает одномерный массив, содержащий подстроки, из строкового выражении с учётом указанного разделителя

    Split(expression[, delimiter[, limit[, compare]]])
  • expression — строковое выражение, содержащая подстроки и разделители. Обязательный параметр.

  • delimiter — текстовый разделитель. Необязательный параметр. Если опущен, то предполагается, что разделителем является символ пробела.

  • limit — количество подстрок, которое необходимо вернуть. -1 или отсутствие параметра означает, что вернуть надо все подстроки.

  • compare — константа, указывающая тип сравнения для символов разделителей. 1 — текстовое сравнение (без учёта регистра), 0 — бинарное сравнение (с учётом регистра).

Результат выглядит так:

Если вы в качестве разделителя укажете пустую строку, то на выходе получите массив, состоящий из одного элемента. Кстати, split всегда возвращает массив с нулевой нижней границей вне всякой зависимости от наличия option base 1.

▲ вверх

Нюансы работы с динамическими массивами


Неинициализированный массив

У динамического массива есть такое промежуточное состояние, когда он уже объявлен, но ещё не содержит никаких элементов.

То есть у переменной динамического массива есть такое состояние, когда мы не можем воспользоваться вспомогательными функциями LBound / UBound для определения его (массива) статуса. Это особенно надо учитывать, когда вы пишите подпрограммы, работающие с массивами. Прежде чем работать (перебирать) массив необходимо убедиться, что он проинициализирован, в противном случае программа вылетит с ошибкой 9.

Для этого я предлагаю пользоваться функцией подобной нижеописанной IsNotEmptyArray:

▲ вверх

Расширение массива

Как правило, расширять динамический массив приходится в цикле. Возможны 2 стратегии: расширение на 1 элемент, как только в этом есть необходимость (назовём это эластичным расширением), и расширение авансом, когда вы увеличиваете верхнюю границу скачками, скажем сразу на 100 элементов. Реализовав оба варианта, я для себя сделал вывод, что авансовое расширение получилось и компактнее, и работает быстрее, так как операция расширения, вообще говоря, затратна и, чем реже вызывается, тем лучше.

Результат:

Авансовый метод вышел даже компактнее

▲ вверх

Удаление массива

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

▲ вверх

Получение массива на основе диапазона Excel

Самый эффективный по скорости способ получить содержимое диапазона Excel для манипулирования в VBA — это скопировать его в массив с элементами Variant. Делается так:

Даже, если вы передаёте в массив столбец или строку, получаемый массив всегда будет иметь 2 измерения. Измерение 1 отвечает за строки, измерение 2 — за столбцы. То есть ячейка C5 будет в элементе arrTemp(5,3). Нижняя граница таких массивов всегда будет начинаться с единицы.

▲ вверх

Дополнительные источники

В качестве источника дополнительной информации по массивам я могу порекомендовать замечательный, исчерпывающий ресурс Чарльза Пирсона (Charles H. Pearson). Его сайт следует штудировать всем, кто серьёзно осваивает VBA. Конкретно по массивам там огромное количество готовых подпрограмм для работы с ними, исходные коды, снабженные подробнейшими комментариями, продвинутые объяснения для копающих в глубину. Без преувеличения великолепный ресурс!

▲ вверх

Читайте также:

Массивы в VBA — Макросы и программы VBA — Excel — Каталог статей

Содержание:

Зачем нужны массивы

Массивы очень упрощают процесс программирования. Без них практически невозможно написать универсальную программу. Например, представьте себе, что вы манипулируете информацией о квартирах жилого дома. Вы объявляете переменные K1 — для первой квартиры, K2 — для второй и так далее. K1=54 будет означать, что площадь первой квартиры 54 кв.м., К2=72 и т.д. Теперь представим, что нам надо подсчитать общую площадь всех квартир в доме. Очевидно, что это что-то типа Total_S = K1+K2+…+Kn. В одном доме у нас 36 квартир, а в другом 144. Представляете бредовость процесса подобного программирования? Если в первом случае я должен буду использовать 36 отдельных переменных для вычисления общей площади, то для второго дома уже 144. Очень быстро вы придёте к мысли, что вам нужна переменная, состоящая из нумерованных ячеек. Тогда обретают смысл все те операторы циклов, входящие в состав любого языка программирования. Но об этом чуть позже…

▲ вверх

Что такое массив

Массив — переменная, состоящая из некоторого количества однотипных элементов. У массива, как и у любой другой переменной, есть имя. А доступ к конкретному элементу массива осуществляется через указание в скобках после имени его индекса. Например, A(5) означает, что я обращаюсь к элементу с индексом 5 массива, имеющего имя A.

▲ вверх

Типы массивов

Массивы в VBA и во многих других языках программирования делятся на 2 класса:

  • Фиксированные массивы. Такие массивы состоят из заранее известного количества элементов. Это количество определяется во время объявления массива и уже не может быть изменено в процессе его жизненного цикла. Вы, конечно же, сможете использовать меньшее количество элементов, но не существует способа увеличить количество элементов сверх объявленного.

  • Динамические массивы. Эти массивы можно «переобъявлять» в процессе жизненного цикла. То есть мы можем управлять количеством элементов динамических масивов в зависимости от наших потребностей. Это очень удобно, так как в подавляющем большинстве случаев программист не может заранее знать, с каким объёмом данных он столкнётся. Если вы собираетесь писать более-менее универсальные программы, то этот тип массивов определенно стоит изучить.

▲ вверх

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


Объявление фиксированных массивов

Рекомендация: при объявлении массивов VBA я советую вам давать всем именам префикс «arr». Я сторонник венгерской нотации.

Как мы видим, тут объявлено 2 одномерных массива arrTemp и arrTest. Одномерные массивы в программировании также часто называют векторами. Типом элементов первого массива является Long, второго массива — String. В этом типе синтаксиса в скобках указан максимальный индекс (верхняя граница ) элемента массива. А что насчёт минимального индекса (нижней границы) массива? По-умолчанию минимальным индексом является ноль. В данном случае стандартное поведение интерпретатора языка VBA можно изменить при помощи оператора option base {0|1}. Option base 1 заставляет VBA считать нижней границей массива — единицу, а не ноль.

Таким образом, по-умолчанию массив arrTemp имеет 11 элементов — от 0 до 10. Но, если в начало модуля, в котором этот массив объявляется, вставить оператор Option Base 1, то массив arrTemp будет иметь 10 элементов — от 1 до 10.

Помимо вышеуказанного вы вправе использовать следующий синтаксис, который НЕ зависит от option base {0|1}:

таким образом вы в явном виде указываете и нижнюю, и верхнюю границы. Как видите, нижняя граница совершенно не обязательно должна начинаться с 0 или 1. Более того, индексы границ могут принимать и отрицательные значения, главное чтобы нижняя была меньше верхней.

Помимо одномерных массивов, можно объявлять и массивы с размерностью больше единицы.

arrMulti — двумерный массив, а arrData3 — трёхмерный. Первый содержит 11*31=341 элемент, второй — 2*3*10=60 элементов. Теоретически допускается объявлять до 60 размерностей массива.

Какие типы данных могут стать элементами массива? Тут всё, как в шутке про фамилию еврея, — абсолютно любой тип данных годится на роль элемента массива, включая объектные типы, User Data Type, другие массивы (через тип Variant). Если вы не указываете при объявлении тип данных массива, то предполагается, что этим типом является тип Variant.

▲ вверх

Объявление динамических массивов

Динамические массивы объявляться так:

Однако, использовать их после такого объявления пока ещё нельзя. Необходимо выделить память под массив. Особенность работы с динамическим массивом как раз состоит в том, что программист отвечает за его своевременное расширение (усечение) в памяти. Для этого существует специальный оператор, который имеет следующий синтаксис:

    ReDim [Preserve] varname(subscripts) [As Type]

Например:

После этого оператора, вы можете использовать элементы массива arrOpen с 0-го по 5-й. Всё, что мы говорили про оператор option base и нижнюю границу, верно и для динамических массивов. Предположим, что вы сохранили информацию в элементах 0-5 и у вас поспела новая порция информации для элементов 6-11. Чтобы разместить в данном массиве новые элементы и не потерять старые, вы должны сделать следующее:

то есть мы тут увеличиваем верхнюю границу массива и используем ключевое слово Preserve, чтобы во время этой операции не потерять текущее содержимое arrOpen, так как в противном случае (без слова Preserve) массив будет расширен, а память заполнена нулями. Вы также вправе вообще не декларировать массив оператором Dim, а сделать это впервые через ReDim и там же указать лип элементов. Но, если вы в первом ReDim (или Dim) указали определенный тип элементов, то в последующих операторах ReDim этот тип переопределён быть не может — возникнет ошибка на этапе компиляции проекта.

▲ вверх

Изменение элементов массива

Пора бы нам уже научиться пользоваться нашими массивами — то есть записывать информацию в их элементы и считывать её оттуда. Это довольно просто:

Как и с обычными переменными запись информации в элемент массива происходит через оператор присваивания (=), но указанием индекса элемента массива.

▲ вверх

Чтение элементов массива

▲ вверх

Определение границ массива

В подпрограммах часто приходится иметь дело с массивами, которые переданы вам в качестве параметра (как это сделать показано ниже), поэтому в этом случае очень актуален вопрос определения нижней и верхней границ индекса массива. Для этого в языке предусмотрены 2 функции: LBound и UBound. Первая возвращает нижнюю границу индекса, вторая — верхнюю.

    LBound( array [, dimension])
    UBound( array [, dimension])

Для одномерных массивов параметр dimension можно не указывать. Для многомерных массивов его указывать необходимо. Кстати, это означает, что, если вы точно не знаете, с каким массивом имеете дело, но необходимо узнать его первую размерность, то лучше использовать вариант UBound(arrTemp,1), а не UBound(arrTemp), так как последний вариант вызовет ошибку, если массив окажется многомерным.

Если вы ошибётесь с указанием правильного индекса массива, то возникнет ошибка периода исполнения с кодом 9. Эта же ошибка возникнет, если вы в функции LBound / UBound укажете несуществующую размерность массива (например, 3 для двумерного массива).

▲ вверх

Перебор элементов массива

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

Наиболее удобный оператор цикла для перебора элементов массива — это безусловно For … Next.

так же есть способ не заботиться об определении нижней и верхней границ, если алгоритм не требует от нас знания текущего индекса массива:

Вы, конечно, можете перебирать массив и в других типах циклов Do … Loop, но, право, смысла и удобства в этом не много. По крайней мере я не сталкивался, кажется, с ситуациями, когда для перебора массива цикл For не подошёл.

▲ вверх

Передача массивов в подпрограммы

Массивы удобнее всего передавать в подпрограммы в виде параметра типа Variant.

Обратите внимание, что функции GetResult в качестве параметра передаются массивы. При чём, в первом случае это массив с типом элементов Long, а во втором — String. За счёт того, что внутри функции используются переменные типа Variant, то сначала функция нам возвращает сумму элементов массива arrIntegers, а во втором результат сложения (конкатенации) строк массива arrStrings. Кроме того, параметр parArray не описан как массив (parArray As Variant), но мы внутри функции GetResult ведём себя с ним, как с массивом (For Each Element In parArray)! Это возможно, так как переменные типа Variant умеют определять, что им присваивается и вести себя далее в соответствии с тем, что они содержат. Если переменной parArray присвоили массив (через вызов функции — строки 17 и 18), то она себя будет вести как массив.

▲ вверх

Массив с элементами типа массив

Продемонстрируем, как можно хранить в качестве элементов массива другие массивы.

Результат отладочной печати:

▲ вверх

Функция Array

Данная функция полезна для создания справочных массивов. Она возвращает переменную типа Variant, содержащую одномерный массив с типом элементов Variant.

    Array( arglist )

Вызов функции без параметров приведёт к возврату массива нулевой длинны. При этом будет наблюдаться интересный эффект LBound вернёт вам 0, а UBound вернёт -1, то есть верхняя граница окажется меньше нижней границы.

▲ вверх

Функция Split

Split возвращает одномерный массив, содержащий подстроки, из строкового выражении с учётом указанного разделителя

    Split(expression[, delimiter[, limit[, compare]]])
  • expression — строковое выражение, содержащая подстроки и разделители. Обязательный параметр.

  • delimiter — текстовый разделитель. Необязательный параметр. Если опущен, то предполагается, что разделителем является символ пробела.

  • limit — количество подстрок, которое необходимо вернуть. -1 или отсутствие параметра означает, что вернуть надо все подстроки.

  • compare — константа, указывающая тип сравнения для символов разделителей. 1 — текстовое сравнение (без учёта регистра), 0 — бинарное сравнение (с учётом регистра).

Результат выглядит так:

Если вы в качестве разделителя укажете пустую строку, то на выходе получите массив, состоящий из одного элемента. Кстати, split всегда возвращает массив с нулевой нижней границей вне всякой зависимости от наличия option base 1.

▲ вверх

Нюансы работы с динамическими массивами


Неинициализированный массив

У динамического массива есть такое промежуточное состояние, когда он уже объявлен, но ещё не содержит никаких элементов.

То есть у переменной динамического массива есть такое состояние, когда мы не можем воспользоваться вспомогательными функциями LBound / UBound для определения его (массива) статуса. Это особенно надо учитывать, когда вы пишите подпрограммы, работающие с массивами. Прежде чем работать (перебирать) массив необходимо убедиться, что он проинициализирован, в противном случае программа вылетит с ошибкой 9.

Для этого я предлагаю пользоваться функцией подобной нижеописанной IsNotEmptyArray:

▲ вверх

Расширение массива

Как правило, расширять динамический массив приходится в цикле. Возможны 2 стратегии: расширение на 1 элемент, как только в этом есть необходимость (назовём это эластичным расширением), и расширение авансом, когда вы увеличиваете верхнюю границу скачками, скажем сразу на 100 элементов. Реализовав оба варианта, я для себя сделал вывод, что авансовое расширение получилось и компактнее, и работает быстрее, так как операция расширения, вообще говоря, затратна и, чем реже вызывается, тем лучше.

Результат:

Авансовый метод вышел даже компактнее

▲ вверх

Удаление массива

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

▲ вверх

Получение массива на основе диапазона Excel

Самый эффективный по скорости способ получить содержимое диапазона Excel для манипулирования в VBA — это скопировать его в массив с элементами Variant. Делается так:

Даже, если вы передаёте в массив столбец или строку, получаемый массив всегда будет иметь 2 измерения. Измерение 1 отвечает за строки, измерение 2 — за столбцы. То есть ячейка C5 будет в элементе arrTemp(5,3). Нижняя граница таких массивов всегда будет начинаться с единицы.

▲ вверх

Дополнительные источники

В качестве источника дополнительной информации по массивам я могу порекомендовать замечательный, исчерпывающий ресурс Чарльза Пирсона (Charles H. Pearson). Его сайт следует штудировать всем, кто серьёзно осваивает VBA. Конкретно по массивам там огромное количество готовых подпрограмм для работы с ними, исходные коды, снабженные подробнейшими комментариями, продвинутые объяснения для копающих в глубину. Без преувеличения великолепный ресурс!

▲ вверх

Читайте также:

Visual Basic с нуля. Глава 10. Массивы. Их границы. Сортировка.

Visual Basic с нуля. Глава 10. Массивы. Их границы. Сортировка.

Массивы.

Массивы, друзья мои, очень простая и крайне необходимая штука. Простой пример: ты считал из директории 50 имен файлов и тебе необходимо как-то поместить их в памяти, что-бы потом с ними работать. Без использования массива, ты должен объявить пятьдесят переменных и в каждую записать имя файла. Это безумие. Но еще большее безумие потом работать с этими переменными, пытаясь найти в них нужные нужные тебе данные. Иное дело массив. Имея его (в хорошем смысле), можно под одним именем запомнить все твои пятьдесят имен файлов и перебирать их сколько угодно, в любом цикле, меняя лишь индекс члена массива. Т.е., другими словами,

Массив — это сколько угодно значений, объединенных одним именем.

Массив, прежде чем использовать, надо объявить. Объявляется он совершенно также как и переменная. Если ты объявишь его локально в процедуре (здесь можно использовать ключевое слово Static), то он будет доступен только в этой процедуре и нигде больше, если в разделе (General)-(Daclarations) формы (c оператором Dim) — то во всей форме, а если тебе нужно объявить его глобально, так, чтобы он был доступен всему проекту, то в стандартном модуле с ключевым словом Public.
Кроме того , массивы бывают статическими и динамическими.

Статические массивы.

Статический массив — это когда ты заранее знаешь, сколько переменных туда нужно будет записать, т.е. если ты объявил массив на 10 членов, то уж туда никак не запихнешь одиннадцать. В форме он объявляется так:

Dim Chislo(9) As Long

Что здесь важно.
Dim — оператор, который точно также, как и при объявлении переменной, объявляет массив и выделяет для нее память.
Chislo — ну это просто имя, придумывается также как и для переменной и отвечает тем же требованиям.
(9) — количество элементов в массиве — их 10. Почему так. Дело в том, что элементы массива нумеруются с нуля, а не с единицы, поэтому у нас десять элементов массива c номерами 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9. Если для каких-то целей такой порядок тебя не устраивает, то используется оператор Option Base 1, который прописывается в разделе Declarations и привязывает первый элемент ВСЕХ, повторяю ВСЕХ, массивов в программе к единице.
As Long — определение типа данных массива так же как тип обычной переменной. Почти всегда все элементы массива имеют один и тот же тип ( в данном случае длинное число Long). На крайняк, если это не так, или если ты не знаешь какого типа будут данные, можно задать тип Variant, но это нежелательно из-за того, что это занимает значительный объем памяти, особенно если массив большой.
Размерность — ее так сразу не заметно, но она здесь присутствует и равна единице, потому, что у на одна циферка (девятка), т.е. наш массив является одномерным — по сути список значений.
Теперь создадим массив для хранения результатов, ну скажем таблицы умножения на 8. Поскольку на ноль умножать бесперспективно, привязываем первый элемент массива к единице и объявляем переменную x для организации цикла For…Next.

Option Explicit
Option Base 1

Dim Chislo(10) As Long
'так как мы используем оператор Option Base, то элементы массива нумеруются с единицы
Dim x As Long

Положим на форму Text1 с установленными свойствами .MultiLine в True, а .ScrollBars — в 2-Вертикаль, а также кнопку Command1. В процедуре Form_Load напишем цикл, который будет присваивать каждому элементу массива значение, соответствующее его номеру, умноженному на 8.

Private Sub Form_Load()
Text1.Text = ""
For x = 1 To 10
Chislo(x) = x * 8
Next x
End Sub

Как видите, в цикле мы вместо номера элемента просто используем значение x, и таким образом перебираются все элементы массива. Теперь мы выведем значения элементов массива в Text1 в процедуре Command1.

Private Sub Command1_Click()
For x = 1 To 10
Text1.Text = Text1.Text & Chislo(x) & vbCrLf
Next x
End Sub

Таким образом наш одномерный массив представляет собой аналог таблицы с одной строчкой:

1 элемент

2 элемент

3 элемент

4 элемент

5 элемент

6 элемент

7 элемент

8 элемент

9 элемент

10 элемент

8

16

34

32

40

48

56

64

72

80

Теперь переделаем его в двухмерный массив, чтобы в еще одну строчку записать множитель, на который умножается число 8. Переделаем наш код на такой:

Option Explicit
Option Base 1

Dim Chislo(10, 2) As Long
Dim x As Long

Private Sub Form_Load()
Text1.Text = «»
For x = 1 To 10
Chislo(x, 1) = x
Chislo(x, 2) = x * 8
Next x

Private Sub Command1_Click()
For x = 1 To 10
Text1.Text = Text1.Text & «8 x » & Chislo(x, 1) & » = » & Chislo(x, 2) & vbCrLf
Next x
End Sub

И наш массив будет представлять собой следующее

 

1 элемент

2 элемент

3 элемент

4 элемент

5 элемент

6 элемент

7 элемент

8 элемент

9 элемент

10 элемент

1 элемент

1

2

3

4

5

6

7

8

9

10

2 элемент

8

16

34

32

40

48

56

64

72

80

таким образом элемент массива Chislo (7,2) будет иметь значение 56.
Обратите внимание, что размерность массива определяет колиство циферек в объявлении. Массив Chislo (10,5) — тоже двухмерный, только строк в табличке было-бы не две, а пять. А объявление трехмерного массива выглядело бы так
Dim(10,5,2).Такую трехмерную таблицу нарисовать мне затруднительно. В принципе VB поддерживает до 64 размерностей массива, но это в голове трудно укладывается.
Все, как видите очень просто. Однако статические массивы используются довольно редко. Чаше мы не знаем сколько данных мы будем иметь и потом ведь хочется дописать при необходимости в массив новые данные. Для этого существуют

Динамические массивы.

Часто возникает ситуация, когда мы не знаем заранее, сколько элементов массива мы будем использовать заранее. Поэтому массив объявляется без размерности, например
Dim Mass () as String
Но, перед его непосредственным использованием, его надо переобъявить c указанием размерности. Делается это с помощью оператора Redim.

Redim Mass (5) as String

Вообще-то, у нас два пути использования динамического массива.
Первый путь, это года мы узнаем (просчитываем) , сколько элементов массива нам нужно, и после этого объявляем массив небходимого нам размера. Однако мне это путь не очень нравится, поскольку, нам приходится задавать два цикла: один — для просчета необходимого количества элементов, второй — для собственно присваивания массиву значений переменных.
Второй путь, это когда мы в одном цикле при нахождении каждого нового данного переобъявляем массив с увеличением количества его элементов. Но этот способ загружает компьютер и может занимать много времени на обработку, особенно если создается большой массив. Происходит это из-за перераспределения элементов массива в памяти всякий раз при его переобъявлении и добавлении нового члена. Но именно такой способ мы применим при разработке программки Scanfiles, которая будет сканировать файлы в выбранной директории, сортировать их по-возрастанию и выводить в Text1. Хочу сразу заметить, что при переобъявлении массива все записанные в него данные стираются — массив обнуляется. Чтобы этого не происходило, надо использовать ключевое слово Peserve:

Redim Preserve Mass (5) as String

Идем дальше. Поместим на форму объекты Dir1 и Text1. Начнем писать код. Обратите внимание, что процедуры Form_Load у нас не будет, так как под это событие обрабатывать нам нечего. Ну-с, фигачим

Option Explicit
'Установим начальную нумерацию массива с единицы, сейчас так удобнее
Option Base 1
'объявим переменные
Dim OurDir As String 'для директории, где будем искать файлы
Dim FileName As String 'для имен находимых файлов
Dim X As Long 'просто для цикла

'и, наконец, наш динамический массив, как строковый
Dim Files() As String

Кроме того, поскольку одни имена — это уж совсем скучно, то мы еще во вторую размерность массива выведем атрибуты файла. Атрибуты, это когда по файлу шлепаешь правой кнопкой мыши и в выпавшем меню выбираешь «Свойства«. Тогда снизу окна этих свойств можно увидеть галочки рядом с загадочными словами «Только чтение», «Скрытый» и «Архивный». Именно эти свойства можно устанавливать или получать с помощью оператора SetAttr и функции GetAttr. Весь геморрой в том, что этот атрибут представляет из себя число, получаемое из суммы значений атрибутов, приведенных в таблице ниже, и чтобы понять, какой атрибут все-таки у файла, нужно «с помощью оператора And выполнить поразрядное сравнение значения». Друзья мои. Это цитату из Help5 я привел для того, чтобы можно было почувствовать разницу между «академическим» и «вольным» изложением проблемы. Короче, привожу таблицу этих атрибутов:

Константа

Значение

Описание

vbNormal

0

Обычный.
vbReadOnly

1

Только для чтения.
vbHidden

2

Скрытый.
vbSystem

4

Системный.
vbDirectory

16

Каталог или папка.
vbArchive

32

Архивный.

Из всей этой дребедни нам нужны три константы: vbArchive, vbReadOnly и vbHidden для этого самого «поразрядного сравнения». Делается это так:
Чтобы узнать, только для чтения ли этот файл:
Переменная = GetAttr(«полный путь к файлу») And vbReadOnly
Если в Переменной не ноль, то файл — только для чтения. Аналогично для других констант.
Чтобы установить аттрибут, например «Архивный» для файла:
SetAttr «C:\Andrey\index.htm», vbReadOnly
при этом уже установленные атрибуты файла сбрасываются. Если надо установить атрибуты «только для чтения» и «архивный»:
SetAttr «C:\Andrey\index.htm», vbReadOnly +vbArchive
Все просто, а по сути — издевательство. Про атрибуты — все. Более интересные данные о файлах мы получим, когда начнем использовать FSO. Но об этом не сегодня.
Итак, для хранения атрибута (на основании «поразрядного сравнения») продолжаем объявлять переменные (еще две)

Dim Attr As Long 'числовая, для атрибута файла
Dim AttributFile As String 'строковая, для записи атрибута в виде слов

Напишем маленькую процедурку для Dir1 на событие Change. Дело в том, что событие Change наступает при двойном клике, а я и хочу, чтобы директория для поиска файлов устанавливалась по двойному клику. В этой процедурке мы очистим Text1 и обнулим переменные, ну и главное, запишем в переменную OurDir полный путь к директории, после чего перейдем к другой поцедуре — ScanDir, где собственно и будем искать файлы и записывать их имена и атрибуты в наш массив Files.

Private Sub Dir1_Change()
Text1.Text = ""
FileName = ""
X = 0
OurDir = Dir1.Path
ScanDir 'переходим к процедуре сканирования файлов
End Sub

Далее в процедуре ScanDir все, с учетом комментариев, понятно:

Private Sub ScanDir()
FileName = Dir(OurDir & "\*.*", 0) 'присваиваем переменной значение функции Dir для всех файлов
ReDim Files(2, 1) 'переобъявляем массив с минимальной размерностью, иначе может возникать ошибка
Do While FileName <> "" 'запускаем цикл, до тех пор, пока Dir не вернет пустую строку
X = X + 1 'счетчик элементов массива
ReDim Preserve Files(2, X) 'переобъявляем массив по счетчику, сохраняя уже имеющиеся в нем данные
AttributFile = "" 'обнуляем переменные
Attr = 0
'проверяем файл на атрибут архивный
Attr = GetAttr(OurDir & "\" & FileName) And vbArchive
If Attr > 0 Then AttributFile = AttributFile & " Архивный"
'проверяем файл на атрибут только для чтения
Attr = GetAttr(OurDir & "\" & FileName) And vbReadOnly
If Attr > 0 Then AttributFile = AttributFile & " Только чтение"
'проверяем файл на атрибут скрытый для порядка, Бейсик все равно не видит такие файлы
Attr = GetAttr(OurDir & "\" & FileName) And vbHidden
If Attr > 0 Then AttributFile = AttributFile & " Скрытый"

Files(1, X) = FileName 'пишем в массив имя файла
Files(2, X) = AttributFile 'пишем в массив атрибут файла
FileName = Dir() 'запускаем функцию Dir без атрибутов
Loop 'и так в цикле, пока файлы в директории не закончатся

If X > 0 Then
Sort ' если хоть один файл найден,
'отправляемся к процедуре сортировки
Else
Text1.Text = "Файлов не найдено" 'в противном случае выводим сообщение.
End If
End Sub


Основная прелесть массивов в том, что с данными, записанными в них, можно что угодно делать: сортировать, разбивать на группы, осуществлять поиск, делать выборки и т.п. Сейчас мы наш массив отсортирум по возрастанию имен файлов. Скажу сразу, что алгоритмы сортировки разработаны и существуют давно. Приводимый в примере был разработан лично мною, а возможное совпадение его с другими алгоритмами совершенно случайно. Но прежде, чем перейти к сортировке, я хочу рассказать вот о чем.
Поскольку количество элементов нашего массива меняется, а для сортировки его с помощью циклов For…Next нам надо точно знать минимальный (нижняя граница) и максимальный (верхняя граница) доступные значения индекса массива, то я использую функции LBound для определения минимального индекса и UBound для определения максимального индекса указанной размерности. Синтаксис их такой

Переменная=LBound(Massive,1) 'возвращает в Переменную минимальный индекс массива Massive по размерности 1.
Переменная=UBound(Massive,1) 'возвращает в Переменную максимальный индекс массива Massive по размерности 1
.

Надо сказать, что размерность — не обязательный параметр и по-умолчанию принимается за единицу.
Теперь перейдем к сортировке массива:

Private Sub Sort() 'процедура сортировки
Dim K As Long
Dim N As Long
Dim y As Long 'просто для цикла For...Next
Dim Peremen As String 'для временного храненения из массива имени файла
Dim Peremen2 As String 'и атрибута файла
Dim NomerPerem As String
Dim NomerPerem2 As String
'сортировка массива
K = LBound(Files, 2) 'присваиваем переменной К начальное значение массива - 1 (нижняя граница)
For y = LBound(Files, 2) To UBound(Files, 2) 'просматриваем все строки массива с нижней до верхней границы
Peremen = Files(1, y) 'присваиваем каждую строку в переменные
Peremen2 = Files(2, y)
'вложенный цикл
For N = y To UBound(Files, 2) 'просматриваем строки массива, начиная с той,
'значения которой храняться в переменных Peremen и Peremen2

If Files(1, N) < Peremen Then ‘если значение в массиве меньше, чем в переменной
Peremen = Files(1, N) ‘то присваиваем переменным Peremen и Peremen2 новые, меньшие значения
Peremen2 = Files(2, N)
K = N ‘присваиваем номер найденного элемента массива переменной K
End If
Next N
‘конец вложенного цикла
NomerPerem = Files(1, y) ‘сохраняем в переменных старые значения строки массива
NomerPerem2 = Files(2, y)
Files(1, y) = Peremen ‘ и присваиваем этой строке массива новые
Files(2, y) = Peremen2
If K > 0 Then ‘если K не ноль,
Files(1, K) = NomerPerem ‘то строке К присваиваем старые значения из строки y
Files(2, K) = NomerPerem2
End If
Peremen = «» ‘обнуляем переменные
Peremen2 = «»
K = 0
Next y
‘конец сортировки
‘просто выводим в Text1 отсортированные значения массива
For X = 1 To UBound(Files, 2)
Text1.Text = Text1.Text & Files(1, X) & Files(2, X) & vbCrLf
Next X
End Sub

Исходник программы можно, как всегда, скачать вверху страницы.

Можно ли присвоить один массив другому не по отдельному элементу (в цикле), а сразу.

Вопрос посетителя сайта Cubic: Можно ли присвоить один массив другому не по отдельному элементу (в цикле), а сразу?


Присвоение массивов.
Visual Basic 6.0 и версии выше дают возможность проводить операции присваивания с массивами точно также, как с переменными. Теперь нет необходимости создавать цикл For…Next для присваивания одного массива другому по каждому элементу. Достаточно написать такой оператор
NewMassive=OldMassive
и содержимое массива OldMassive присвоится массиву NewMassive.
Однако при этом следут учитывать, что для исключинения ошибок при таком присвоении, желательно соблюдать одинаковую размерность и тип массивов. Хотя при присвоении динамического массива динамическому массиву, массив в левой части оператора изменяется, как бы подстраивается под оператор в правой части. Однако при работе со статическими массивами возможна ошибка компиляции. Кроме того при присвоении, например массива типа Long типу Integer может возникнуть ошибка переполнения (Owerflow). В программе операция присвоения может выглядеть приблизиельно так (на форме должны быть кнопка Command1 и текстбокс Text1):

Option Explicit
Dim
OldMassive() As Long
Dim NewMassive() As Long

Private Sub Command1_Click()
Dim x As Long

For x = 0 To 999 ‘просто заполнение массива цифрами
ReDim Preserve OldMassive(x)
OldMassive(x) = x
Next x

NewMassive = OldMassive ‘присоение массивов

For x = 0 To UBound(NewMassive) ‘ считывание нового массива в Text1
Text1.Text = Text1.Text & NewMassive(x) & vbCrLf
Next x
End Sub

Я думаю, особых комментариев здесь не требуется.
Сайт создан в системе uCoz

4. Массивы — Знакомство с Visual Basic

Заполнение массивов

Типы массивов и объявление массива. Массив является набором переменных одного типа, объединенных одним именем. Массивы, как и переменные, могут быть различных типов: числовые, строковые и т. д.

Массив состоит из пронумерованной последовательности элементов. Номера в этой последовательности называются индексом; индекс может принимать целочисленные значения.

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

Массив может быть одномерным или многомерным. Размерность массива соответствует числу индексов, необходимых для идентификации отдельного элемента. Можно задать до 32 индексов, хотя случаи использования более трех индексов очень редки.

Например, одномерный строковый массив, содержащий 33 буквы русского алфавита, можно представить себе в виде

Индекс

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Элементы массива

А

Б

В

Г

Д

В

Ё

Ж

3

И

И

К

Л

М

Н

О

П

Индекс

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

 

Элементы массива

Р

С

Т

У

Ф

Х

Ц

Ч

Ш

Щ

Ъ

Ы

Ь

Э

Ю

Я

 

Индекс может принимать целочисленные значения от минимального до максимального индекса (в данном массиве от 0 до 32). Каждый элемент массива обладает собственным значением (в данном массиве значением элемента с индексом 4 является строка «д»). Размер массива определяется количеством элементов в массиве (в данном массиве 33 элемента).

Объявление массива производится аналогично объявлению переменных, необходимо только дополнительно указать максимальный индекс или диапазон изменения индекса

Обращение к элементу массива производится по его имени, состоящему из имени массива, и значения индекса, например N (5) .

Заполнение массива. Для начала работы с массивом необходимо его предварительно заполнить, т. е. присвоить элементам массива определенные значения. Это можно сделать различными способами:

1.     заполнить массив случайными числами;

2.     заполнить массив символами с клавиатуры;

3.     заполнить массив из файла.

Проект «Заполнение массива». Заполнить числовой массив десятью случайными числами,

1. Поместить на форму

список ListBoxl, который будет использоваться для вывода целочисленного массива, заполненного случайными числами;

 кнопки Buttonl для создания обработчиков событий.

Заполним числовой массив N (I) целыми случайными числами в интервале от 1 до 100.

На языке Visual Basic .NET для генерации последовательности случайных чисел используем функцию Rnd (). При запуске программы функция Rnd () дает псевдослучайную (т. е. каждый раз повторяющуюся) последовательность чисел в интервале 0 < X < 1.

Тогда получение целочисленной последовательности случайных чисел на интервале 0 < X < 100 достигается использованием функции выделения целой части числа:

A(i) = Int(Rnd() * 100)

Создание обработчика события заполнения массива случайными числами на языке Visual Basic .NET:

Public Class Form1

    Dim A(10) As Byte

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ListBox1.Items.Clear()

        Randomize()

        For i = 0 To 9

            A(i) = Int(Rnd() * 100)

            ListBox1.Items.Add(Val(A(i)))

        Next i

    End Sub

End Class

 

Для ввода элементов массива с клавиатуры можно использовать функцию InputBox () . Аргументами этой функции являются две строки, которые отображаются в диалоговом окне ввода, а значением функции — символ, введенный пользователем.

Создадим аналогичную форму

Dim A(4), I As Byte

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ListBox1.Items.Clear()

        For I = 0 To 4

            A(I) = InputBox(«Введите элементы массива»)

            ListBox1.Items.Add(A(I))

        Next I

    End Sub

Заполним строковый массив буквами русского алфавита из текстового файла. Создадим текстовый файл, содержащий буквы русского алфавита. Такие текстовые файлы должны содержать только коды самих символов (не должны содержать управляющие коды форматирования текста, тэги языка HTML и т. д.) и, следовательно, должны создаваться в простейших текстовых редакторах типа Блокнот. Сохранять файл целесообразнее в папке Debug, иначе придётся в программе указывать полный путь к файлу

В обработчике события присвоим переменной значение с использованием метода открытия файла OpenText (), аргументом которого является имя открываемого файла text.txt. В цикле со счетчиком произведем чтение букв алфавита из файла с использованием метода ReadLine () и выведем буквы в список.

Dim I As Byte

    Dim A(32) As String

    Dim sr As System.IO.StreamReader

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ListBox1.Items.Clear()

        sr = System.IO.File.OpenText(«Text.txt»)

        For I = 0 To 32

            A(I) = sr.ReadLine

            ListBox1.Items.Add(A(I))

        Next I

    End Sub

Поиск максимального элемента массива

Поиск в строковых массивах обычно реализуется в форме поиска индекса элемента массива, для которого значение элемента совпадает с заданным. В числовых массивах обычно производится поиск минимального или максимального элемента.

Проект «Поиск в массиве». Разработать проект, в котором числовой массив, содержащий 10 элементов, заполняется случайными числами в диапазоне от 0 до 100. Осуществить в этом числовом массиве поиск максимального элемента и его индекса.

Поместить на форму

•  список ListBoxl для вывода значений индекса элементов массива;

•  список ListBox2 для вывода значений элементов массива;

•  надпись Label1 для вывода индекса максимального элемента;

•  надпись  Label2  для  вывода значения максимального элемента;

•  кнопку Button1 для создания обработчика события;

•  две надписи для вывода поясняющих текстов.

Создадим обработчик события для заполнения целочисленного массива случайными числами и поиска максимального элемента и его индекса:

1)  Объявим целочисленные переменные I и Мах, а также целочисленный массив А (9) , содержащий десять элементов.

2) Заполним массив целыми случайными числами от 0 до 100.

3)  Будем считать, что сначала максимальный элемент равен первому элементу массива, т. е. Мах = 0 и А (Мах)   = А (0).

4)  Затем в цикле со счетчиком I с использованием оператора ветвления последовательно сравним максимальный элемент массива (элемент массива с индексом 0) со всеми остальными элементами. Если какой-либо элемент окажется больше, присвоим переменной Мах индекс этого элемента.

5)  Результат поиска, т. е. индекс максимального элемента и сам максимальный элемент, выведем на надписи.

 

   

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ListBox1.Items.Clear()

        ListBox2.Items.Clear()

        Randomize()

        For I = 0 To 9

            A(I) = Int(Rnd() * 100)

            ListBox1.Items.Add(I)

            ListBox2.Items.Add(A(I))

        Next I

        max = 0

        A(max) = A(0)

        For I = 1 To 9

            If A(I) > A(max) Then

                A(max) = A(I)

                max = I

            End If

        Next I

        Label3.Text = Val(max)

        Label4.Text = Val(A(max))

    End Sub

Сортировка методом обмена

В основе алгоритма лежит обмен соседних элементов массива. Каждый элемент массива, начиная с первого, сравнивается со следующим, и если он больше следующего, то элементы меняются местами. Таким образом, элементы с меньшим значением продвигаются к началу массива (всплывают), а элементы с большим значением — к концу массива (тонут). Поэтому данный метод сортировки обменом иногда называют методом «пузырька». Этот процесс повторяется столько раз, сколько элементов в массиве, минус единица.

Поместить на форму

список ListBoxl для вывода значений индекса элементов массива;

список ListBox2 для вывода значений элементов массива;

кнопку Button1 для ввода массива

Button2 для создания обработчика события;

 

 

Dim A(9), i, j, buf As Byte

    Dim C As Boolean

……………

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        j = 1 ‘ подсчет шагов сортировки

        Do

            ListBox2.Items.Add(«Шаг» & j)

            j = j + 1

            C = False ‘ предположим что массив отсортирован

            For i = 0 To 8

                If A(i) > A(i + 1) Then

                    buf = A(i)

                    A(i) = A(i + 1)

                    A(i + 1) = buf

                    C = True

                End If

            Next i

            For i = 0 To 9

                ListBox2.Items.Add(A(i))

            Next i

        Loop Until Not C

        ListBox2.Items.Add(«сортировка завершена»)

    End Sub

Самостоятельная работа


Задание №1

Дан одномерный массив А, состоящий из 10 элементов. Подсчитать количество положительных элементов и создать массив В заменив в массиве А положительные элементы их индексами. Массив вводится с клавиатуры.

Указание к выполнению

1.     Разместите на форме два элемента ListBox, для ввода массива и вывода массива В

2.     Два компонента Button для начала ввода и выполнения расчетов

3.     Компонент Label для вывода суммы

Задание №2

Даны два одномерных массива А и В одинакового размера. Получить третий массив С, элементами которого являются, парные суммы элементов исходных массивов, в первом массиве элементы брать с начала, во втором с конца. Массивы заполняются случайными числами.

Указание к выполнению

1.     Разместите на форме три элемента ListBox, для ввода массивов А и В и вывода массива С

2.     Два компонента Button для начала ввода и выполнения расчетов

 

Задание №3

Дан одномерный массив состоящий из 20 элементов. Найти сумму элементов массива, принадлежащих промежутку от А до В. Массив вводится из файла.

Указание к выполнению

1.     Разместите на форме элемент ListBox, для ввода массивов

2.     Два компонента Button для начала ввода и выполнения расчетов

3.     Два элемента TextBox для ввода значений промежутков

4.     Три компонента Label для комментариев и один компонент Label для вывода суммы.

 

Задание №3

Коэффициенты многочлена хранятся в целочисленном массиве А(N), n – натуральное число, степень многочлена. Вычислить значение этого многочлена в точке X (т. е. Y:= a[n]*(x  в степени n)+ a[n-1]*(x в степени n-1)…+a[1]*x+a[0]). Массив вводится из файла

Указание к выполнению

1.     Разместите на форме элемент ListBox, для ввода массивов

2.     Два компонента Button для начала ввода и выполнения расчетов

3.     Элемента TextBox для ввода значения X

4.     Три компонента Label для комментариев и один компонент Label для вывода суммы.

5.     Для возведения в степень применяется функция Pow, для использования данной функции в начале программного кода подключите пространство имен:

Imports System.Math

Задание №4

В массиве А обменять последний четный и первый не четный элементы. Массив вводится с клавиатуры.

Указание к выполнению

1.     Разместите на форме элемент ListBox, для ввода массива

2.     Компонент Button для начала ввода и выполнения расчетов

 

массивов — Visual Basic | Документы Microsoft

  • 28 минут на чтение

В этой статье

Массив — это набор значений, которые называются элементами , которые логически связаны друг с другом. Например, массив может состоять из количества учеников в каждом классе гимназии; каждый элемент массива — это количество учеников в одном классе.Точно так же массив может состоять из оценок учащегося за класс; каждый элемент массива относится к одному классу.

Возможно отдельные переменные для хранения каждого из наших элементов данных. Например, если наше приложение анализирует оценки учащихся, мы можем использовать отдельную переменную для оценки каждого учащегося, например, englishGrade1 , englishGrade2 и т. Д. Этот подход имеет три основных ограничения:

  • Во время проектирования мы должны точно знать, сколько сортов нам нужно обработать.
  • Обработка большого количества сортов быстро становится громоздкой. Это, в свою очередь, увеличивает вероятность возникновения серьезных ошибок в приложении.
  • Сложно обслуживать. Каждая новая оценка, которую мы добавляем, требует, чтобы приложение было изменено, перекомпилировано и повторно развернуто.

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

Несколько быстрых примеров перед объяснением:

  'Объявить одномерный массив из 5 чисел.Тусклые числа (4) как целое число

'Объявите одномерный массив и установите для него 4 значения.
Тусклые числа = новое целое число () {1, 2, 4, 8}

'Измените размер существующего массива на 16 элементов и сохраните текущие значения.
Номера ReDim Preserve (15)

'Переопределите размер существующего массива и сбросьте значения.
ReDim числа (15)

'Объявите многомерный массив 6 x 6.
Тусклая матрица (5, 5) как двойная

'Объявите многомерный массив 4 x 3 и установите значения элементов массива.
Тусклая матрица = новое целое число (3, 2) {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}

'Объявить зубчатый массив
Тусклые продажи () () как двойное = новое двойное (11) () {}
  

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

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

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

В следующем примере содержится код Visual Basic, который создает и использует массив:

 
Модуль SimpleArray
   Публичная подпрограмма Main ()
      'Объявить массив из 7 элементов.
      Тусклые студенты (6) как целое число

      'Присвойте значения каждому элементу.студенты (0) = 23
      студенты (1) = 19
      студенты (2) = 21
      студенты (3) = 17
      студенты (4) = 19
      студенты (5) = 20
      студенты (6) = 22
      
      'Показать значение каждого элемента.
      Для ctr как целое число = от 0 до 6
         Тусклая оценка как строка = If (ctr = 0, "детский сад", $ "grade {ctr}")
         Console.WriteLine ($ "Учащиеся в {классе}: {учащиеся (ctr)}")
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'Ученики детского сада: 23
'Учащимся 1 класса: 19
Ученики 2 класса: 21
'Учащимся 3 класса: 17
'Учащимся 4 класса: 19
'Учащимся 5 класса: 20
'Учащимся 6 класса: 22
  

Пример выполняет три функции:

  • Он объявляет массив студентов с семью элементами.Число 6 в объявлении массива указывает последний индекс в массиве; это на единицу меньше, чем количество элементов в массиве.
  • Он присваивает значения каждому элементу в массиве. Доступ к элементам массива осуществляется с помощью имени массива и включения индекса отдельного элемента в круглые скобки.
  • Он перечисляет каждое значение массива. В примере используется оператор For для доступа к каждому элементу массива по его порядковому номеру.

Массив студентов в предыдущем примере является одномерным массивом, поскольку он использует один индекс.Массив, в котором используется более одного индекса или нижнего индекса, называется многомерным . Дополнительные сведения см. В оставшейся части этой статьи и в разделе «Измерения массива в Visual Basic».

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

Вы можете определить размер массива несколькими способами:

  • Вы можете указать размер при объявлении массива:

      'Объявите массив из 10 элементов.
    Тусклый груз Вес (9) В двойном размере
    'Объявите массив 24 x 2.
    Тусклые почасовые температуры (23, 1) как целое число
    'Объявите зубчатый массив из 31 элемента.Dim januaryInquiries (30) () В виде строки
      
  • Вы можете использовать предложение New , чтобы указать размер массива при его создании:

      'Объявите массив из 10 элементов.
    Dim cargoWeights () As Double = Новый двойной (9) {}
    'Объявите массив 24 x 2.
    Dim hourlyTemperatures (,) As Integer = New Integer (23, 1) {}
    'Объявите зубчатый массив из 31 элемента.
    Dim januaryInquiries () () As String = New String (30) () {}
      

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

  'Назначьте новый размер массива и сохраните текущие значения.
ReDim Preserve Cargo Масса (20)
'Назначьте новый размер массива и сохраните только первые пять значений.
ReDim Preserve Cargo Масса (4)
'Назначьте новый размер массива и отбросьте все текущие значения элементов.ReDim CargoWeights (15)
  

Для получения дополнительной информации см. Заявление ReDim.

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

Вы можете получить доступ к каждому местоположению в массиве, используя индекс типа Integer . Вы можете сохранять и извлекать значения в массиве, ссылаясь на каждое местоположение массива, используя его индекс, заключенный в круглые скобки. Индексы для многомерных массивов разделяются запятыми (,). Вам нужен один индекс для каждого измерения массива.

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

 
Пример модуля
   Публичная подпрограмма Main ()
      'Создайте целочисленный массив из 10 элементов.
      Тусклые числа (9) как целое число
      Значение затемнения как целое число = 2
        
      «Запишите в него ценности.
      Для ctr как целое число = от 0 до 9
         числа (ctr) = значение
         значение * = 2
      Следующий
        
      'Прочтите и просуммируйте значения массива.
      Дим-сумма как целое число
      Для ctr как целое число = от 0 до 9
         сумма + = числа (ctr)
      Следующий
      Console.WriteLine ($ "Сумма значений равна {sum: N0}")
    Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'Сумма значений составляет 2 046
  

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

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

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

  'Литералы массива с явным определением типа.
Тусклые числа = новое целое число () {1, 2, 4, 8}
'Литералы массива с выводом типа.
Тусклые удвоения = {1,5, 2, 9,9, 18}
'Литералы массива с явным определением типа.Тусклые статьи () как String = {"the", "a", "an"}

'Литералы массива с явным определением типа расширения.
Затемнить значения () As Double = {1, 2, 3, 4, 5}
  

Когда вы используете вывод типа, тип массива определяется доминирующим типом в списке литеральных значений. Доминирующий тип — это тип, до которого могут расширяться все другие типы в массиве. Если этот уникальный тип не может быть определен, доминирующим типом является уникальный тип, до которого могут сузиться все другие типы в массиве.Если ни один из этих уникальных типов не может быть определен, доминирующим типом является Объект . Например, если список значений, который передается в литерал массива, содержит значения типа Integer , Long и Double , результирующий массив будет иметь тип Double . Поскольку Integer и Long расширяются только до Double , Double является доминирующим типом. Для получения дополнительной информации см. Расширение и сужение преобразований.

Примечание

Выявление типа можно использовать только для массивов, которые определены как локальные переменные в члене типа. Если явное определение типа отсутствует, массивы, определенные с помощью литералов массива на уровне класса, имеют тип Object [] . Для получения дополнительной информации см. Выведение локального типа.

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

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

  'Создайте и заполните массив 2 x 2.
Тусклая сетка1 = {{1, 2}, {3, 4}}
'Создайте и заполните массив 2 x 2 3 элементами.
Затемнить сетку2 (,) = {{1, 2}, {3, 4}, {5, 6}}
  

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

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

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

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

Итерация по массиву

При итерации по массиву вы получаете доступ к каждому элементу в массиве от самого низкого индекса до самого высокого или от самого высокого до самого низкого. Как правило, для перебора элементов массива используют либо оператор For … Next, либо оператор For Each … Next. Если вы не знаете верхних границ массива, вы можете вызвать метод Array.GetUpperBound, чтобы получить максимальное значение индекса. Хотя наименьшее значение индекса почти всегда равно 0, вы можете вызвать метод Array.GetLowerBound, чтобы получить наименьшее значение индекса.

В следующем примере выполняется итерация по одномерному массиву с помощью оператора For ... Next .

 
Модуль IterateArray
   Публичная подпрограмма Main ()
      Тусклые числа = {10, 20, 30}

      Для индекса = 0 К числам. GetUpperBound (0)
         Console.WriteLine (числа (индекс))
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'10
'20
'30

  

В следующем примере выполняется итерация по многомерному массиву с использованием объекта For...Следующая выписка . Метод GetUpperBound имеет параметр, определяющий размер. GetUpperBound (0) возвращает наивысший индекс первого измерения, а GetUpperBound (1) возвращает наивысший индекс второго измерения.

 
Модуль IterateArray
   Публичная подпрограмма Main ()
      Тусклые числа = {{1, 2}, {3, 4}, {5, 6}}

      Для index0 = 0 Для чисел.GetUpperBound (0)
         Для index1 = 0 К числам. GetUpperBound (1)
            Console.Write ($ "{числа (индекс0, индекс1)}")
         Следующий
         Приставка.WriteLine ()
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
' Выход
'1 2
'3 4
'5 6
  

В следующем примере оператор For Each … Next используется для перебора одномерного и двумерного массивов.

 
Модуль IterateWithForEach
   Публичная подпрограмма Main ()
      'Объявить и перебрать одномерный массив.
      Тусклые числа1 = {10, 20, 30}
      
      Для каждого числа В числах1
         Console.WriteLine (число)
      Следующий
      Приставка.WriteLine ()
      
      Тусклые числа = {{1, 2}, {3, 4}, {5, 6}}

      Для каждого числа В числах
         Console.WriteLine (число)
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'10
'20
'30
'
'1
'2
'3
'4
'5
'6
  

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

Размер массива — произведение длин всех его измерений. Он представляет собой общее количество элементов, содержащихся в данный момент в массиве. Например, в следующем примере объявляется двумерный массив с четырьмя элементами в каждом измерении.Как видно из выходных данных примера, размер массива равен 16 (или (3 + 1) * (3 + 1).

 
Пример модуля
   Публичная подпрограмма Main ()
      Dim arr (3, 3) как целое число
      Console.WriteLine (arr.Length)
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'16
  

Примечание

Это обсуждение размера массива не относится к зубчатым массивам. Для получения информации о зубчатых массивах и определении размера зубчатого массива см. Раздел «Неровные массивы».

Вы можете узнать размер массива, используя свойство Array.Length. Вы можете найти длину каждого измерения многомерного массива с помощью метода Array.GetLength.

Вы можете изменить размер переменной массива, назначив ей новый объект массива или используя оператор ReDim Statement. В следующем примере оператор ReDim используется для изменения массива из 100 элементов на массив из 51 элемента.

 
Пример модуля
   Публичная подпрограмма Main ()
      Dim arr (99) как целое число
      Приставка.WriteLine (длина строки)
      
      Редим обр (50)
      Console.WriteLine (arr.Length)
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
100
'51

 
  

При работе с размером массива следует помнить о нескольких вещах.

Размер Длина Индекс каждого измерения отсчитывается от 0, что означает, что он находится в диапазоне от 0 до его верхней границы. Следовательно, длина данного измерения на единицу больше заявленной верхней границы этого измерения.31) — 1. Однако общий размер массива также ограничен объемом памяти, доступной в вашей системе. Если вы попытаетесь инициализировать массив, превышающий объем доступной памяти, среда выполнения выдает исключение OutOfMemoryException.
Размер и размер элемента Размер массива не зависит от типа данных его элементов. Размер всегда представляет собой общее количество элементов, а не количество байтов, которые они потребляют в памяти.
Потребление памяти Делать какие-либо предположения относительно того, как массив хранится в памяти, небезопасно.Хранилище различается на платформах с разной шириной данных, поэтому один и тот же массив может потреблять больше памяти в 64-битной системе, чем в 32-битной системе. В зависимости от конфигурации системы, когда вы инициализируете массив, среда CLR может назначать хранилище либо для упаковки элементов как можно ближе друг к другу, либо для выравнивания их всех по естественным границам оборудования. Кроме того, массив требует накладных расходов на хранилище для своей управляющей информации, и эти накладные расходы увеличиваются с каждым добавленным измерением.

Тип массива

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

Каждый массив наследуется от класса System.Array, и вы можете объявить переменную типа Array , но вы не можете создать массив типа Array .Например, хотя следующий код объявляет, что переменная arr имеет тип Array и вызывает метод Array.CreateInstance для создания экземпляра массива, типом массива оказывается Object [].

 
Пример модуля
   Публичная подпрограмма Main ()
      Dim arr As Array = Array.CreateInstance (GetType (Object), 19)
      Console.WriteLine (arr.Length)
      Console.WriteLine (arr.GetType (). Имя)
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'19
'     Объект[]
  

Кроме того, оператор ReDim не может работать с переменной, объявленной как тип , массив .По этим причинам и для обеспечения безопасности типов рекомендуется объявлять каждый массив как определенный тип.

Вы можете узнать тип данных массива или его элементов несколькими способами.

  • Вы можете вызвать метод GetType для переменной, чтобы получить объект Type, представляющий тип времени выполнения переменной. Объект Type содержит обширную информацию о своих свойствах и методах.
  • Вы можете передать переменную в функцию TypeName, чтобы получить String с именем типа времени выполнения.

В следующем примере вызываются как метод GetType , так и функция TypeName для определения типа массива. Тип массива — байт (,) . Обратите внимание, что свойство Type.BaseType также указывает, что базовым типом массива байтов является класс Array.

 
Пример модуля
   Публичная подпрограмма Main ()
      Тусклые байты (9,9) как байты
      Console.WriteLine ($ "Тип массива {nameof (bytes)}: {bytes.GetType (). Name}")
      Console.WriteLine ($ "Базовый класс {nameof (bytes)}: {bytes.GetType (). BaseType.Name} ")
      Console.WriteLine ()
      Console.WriteLine ($ "Тип массива {nameof (bytes)}: {TypeName (bytes)}")
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'Тип байтового массива: Byte [,]
'Базовый класс байтов: Массив
'
'Тип байтового массива: Byte (,)


  

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

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

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

В следующем примере функция GetNumbers возвращает Integer () , одномерный массив типа Integer .Процедура ShowNumbers принимает аргумент Integer () .

 
Модуль ReturnValuesAndParams
   Публичная подпрограмма Main ()
      Размыть числа как целые () = GetNumbers ()
      ShowNumbers (числа)
   Конец подписки

   Частная функция GetNumbers () как целое число ()
      Уменьшить число как целое () = {10, 20, 30}
      Возврат номеров
   Конечная функция

   Private Sub ShowNumbers (числа как целые ())
      Для индекса = 0 К числам. GetUpperBound (0)
         Console.WriteLine ($ "{числа (индекс)}")
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'10
'20
'30
    
  

В следующем примере функция GetNumbersMultiDim возвращает Integer (,) , двумерный массив типа Integer .Процедура ShowNumbersMultiDim принимает аргумент Integer (,) .

 
Пример модуля
   Публичная подпрограмма Main ()
      Размыть числа как целое число (,) = GetNumbersMultidim ()
      ShowNumbersMultidim (числа)
   Конец подписки

   Частная функция GetNumbersMultidim () как целое число (,)
      Тусклые числа как целые (,) = {{1, 2}, {3, 4}, {5, 6}}
      Возврат номеров
   Конечная функция

   Private Sub ShowNumbersMultidim (числа как целые (,))
      Для index0 = 0 Для чисел.GetUpperBound (0)
         Для index1 = 0 до чисел.GetUpperBound (1)
            Console.Write ($ "{числа (индекс0, индекс1)}")
         Следующий
         Console.WriteLine ()
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'1 2
'3 4
'5 6

  

Зубчатые массивы

Иногда структура данных в вашем приложении двумерная, но не прямоугольная. Например, вы можете использовать массив для хранения данных о высокой температуре каждого дня месяца. Первое измерение массива представляет месяц, а второе измерение представляет количество дней, а количество дней в месяце неоднородно.Зубчатый массив , который также называют массивом массивов , разработан для таких сценариев. Неровный массив — это массив, элементы которого также являются массивами. Зубчатый массив и каждый элемент зубчатого массива могут иметь одно или несколько измерений.

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

  Система импорта. Глобализация

Модуль JaggedArray
   Публичная подпрограмма Main ()
      'Объявите зубчатый массив из 12 элементов. Каждый элемент представляет собой массив Double.
      Тусклые продажи (11) () как двойные
      'Установите для каждого элемента массива продаж двойной массив подходящего размера.
      Для месяца как целое число = от 0 до 11
         «Количество дней в месяце определяет подходящий размер.
         Dim daysInMonth As Integer =
            DateTime.DaysInMonth (Год (сейчас), месяц + 1)
         продажи (месяц) = Новый двойной (daysInMonth - 1) {}
      Следующий

      'Сохранять значения в каждом элементе.Для месяца как целое число = от 0 до 11
         Для dayOfMonth = 0 К продажам (месяц) .GetUpperBound (0)
            продажи (месяц) (dayOfMonth) = (month * 100) + dayOfMonth
         Следующий
      Следующий

      'Получить и отобразить значения массива.
      Тусклые monthNames = DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames
      'Показать названия месяцев.
      Console.Write ("")
      Для ctr = 0 В sales.GetUpperBound (0)
         Console.Write ($ "{monthNames (ctr)}")
      Следующий
      Console.WriteLine ()
      'Отображать данные за каждый день каждого месяца.Для dayInMonth = от 0 до 30
         Console.Write ($ "{dayInMonth + 1,2}.")
         Для monthNumber = 0 Для продажи.GetUpperBound (0)
            Если dayInMonth> sales (monthNumber) .GetUpperBound (0), то
               Console.Write ("")
            Еще
               Console.Write ($ "{продажи (monthNumber) (dayInMonth), - 5}")
            Конец, если
         Следующий
         Console.WriteLine ()
      Следующий
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'Янв фев мар апр май июн июл авг сен окт ноя дек
'1.0100200300400500600700800900 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. 8108 208 308 408 508 608 708 808 908 1008 1108
'10. 9 109 209 309 409 509 609 709 809 909 1009 1109
'11. 10110210310410510610710810910 1010 1110
'12. 11 111 211 311 411 511 611 711 811 911 1011 1111
13.12112 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 10 15 11 15
'17. 16116 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.20120220320420520620720820920 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
  

В предыдущем примере значения неровному массиву присваиваются поэлементно с помощью цикла For ... Next . Вы также можете присвоить значения элементам зубчатого массива, используя литералы вложенных массивов. Однако попытка использовать литералы вложенных массивов (например, Dim valuesjagged = {{1, 2}, {2, 3, 4}} ) генерирует ошибку компилятора BC30568. Чтобы исправить ошибку, заключите литералы внутреннего массива в круглые скобки.Скобки заставляют вычислять выражение литерала массива, а полученные значения используются с литералом внешнего массива, как показано в следующем примере.

 
Пример модуля
   Публичная подпрограмма Main ()
      Тусклые значения1d = {1, 2, 3}
      Dim values2d = {{1, 2}, {2, 3}, {3, 4}}
      Тусклые значенияjagged = {({1, 2}), ({2, 3, 4})}
   Конец подписки
Конечный модуль

  

Неровный массив — это одномерный массив, элементы которого содержат массивы. Следовательно, свойство Array.Length и массив .GetLength (0) метод возвращает количество элементов в одномерном массиве, а Array.GetLength (1) генерирует исключение IndexOutOfRangeException, поскольку зубчатый массив не является многомерным. Вы определяете количество элементов в каждом подмассиве, извлекая значение свойства Array.Length каждого подмассива. В следующем примере показано, как определить количество элементов в неровном массиве.

 
Пример модуля
   Публичная подпрограмма Main ()
      Тусклый зазубренный = {({1, 2}), ({2, 3, 4}), ({5, 6}), ({7, 8, 9, 10})}
      Приставка.WriteLine ($ "Значение jagged.Length: {jagged.Length}.")
      Общий тусклый = зубчатый. Длина
      Для ctr As Integer = 0 To jagged.GetUpperBound (0)
         Console.WriteLine ($ "Элемент {ctr + 1} имеет {jagged (ctr) .Length} элементов.")
         всего + = зубчатый (ctr). Длина
      Следующий
      Console.WriteLine ($ "Общее количество элементов в массиве с зазубринами: {total}")
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
'Значение jagged.Length: 4.
«Элемент 1 состоит из 2 элементов.«Элемент 2 состоит из 3 элементов.
«Элемент 3 состоит из 2 элементов.
«Элемент 4 состоит из 4 элементов.
'Общее количество элементов в зубчатом массиве: 15

  

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

Visual Basic различает неинициализированный массив (массив со значением Nothing ) и массив нулевой длины или пустой массив (массив, не имеющий элементов). Неинициализированный массив — это массив, размеры которого не были измерены или были любые присвоенные ему значения. Например:

  Dim arr () как строка
  

Объявлен массив нулевой длины с размером -1.Например:

  Dim arrZ (-1) как строка
  

Вам может потребоваться создать массив нулевой длины в следующих случаях:

  • Без риска возникновения исключения NullReferenceException ваш код должен обращаться к членам класса Array, таким как Length или Rank, или вызывать функцию Visual Basic, например UBound.

  • Вы хотите, чтобы ваш код был простым, не проверяя Nothing как особый случай.

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

Разделение массива

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

Примечание

В этом разделе не обсуждается разделение одной строки на массив строк на основе некоторого разделителя. Для получения информации о разделении строки см. Метод String.Split.

Наиболее распространенные критерии разделения массива:

  • Количество элементов в массиве.Например, вы можете захотеть разбить массив, состоящий из более чем указанного количества элементов, на несколько примерно равных частей. Для этой цели вы можете использовать значение, возвращаемое методом Array.Length или Array.GetLength.

  • Значение элемента, которое служит разделителем, указывающим, где следует разбить массив. Вы можете найти конкретное значение, вызвав методы Array.FindIndex и Array.FindLastIndex.

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

В следующем примере массив разбивается на два массива примерно равного размера. (Если общее количество элементов массива нечетное, в первом массиве на один элемент больше, чем во втором.)

 
Пример модуля
   Публичная подпрограмма Main ()
      'Создайте массив из 100 элементов.
      Dim arr (99) как целое число
      'Заполните массив.
      Dim rnd As new Случайно ()
      Для ctr = 0 Для arr.GetUpperBound (0)
         arr (ctr) = rnd.Next ()
      Следующий
      
      'Определите, сколько элементов должно быть в каждом массиве.Тусклый делитель = 2
      Тусклый остаток как целое число
      Тусклая граница = Math.DivRem (arr.GetLength (0), делитель, остаток)
            
      'Скопируйте массив.
      Dim arr1 (граница - 1 + остаток), arr2 (граница - 1) как целое число
      Array.Copy (arr, 0, arr1, 0, граница + остаток)
      Array.Copy (arr, граница + остаток, arr2, 0, arr.Length - граница)
   Конец подписки
Конечный модуль

  

В следующем примере массив строк разбивается на два массива в зависимости от наличия элемента со значением «zzz», который служит разделителем массива.Новые массивы не включают элемент, содержащий разделитель.

 
Пример модуля
   Публичная подпрограмма Main ()
      Dim rnd As New Random ()
      
      'Создайте массив из 100 элементов.
      Dim arr (99) как строка
      'Заполните каждый элемент произвольным символом ASCII.
      Для ctr = 0 Для arr.GetUpperBound (0)
         arr (ctr) = ChrW (Rnd.Next (& h31, & h7F))
      Следующий
      'Получите случайное число, которое будет представлять точку для вставки разделителя.
      обр (рнд.Далее (0, arr.GetUpperBound (0))) = "zzz"

      'Найдите разделитель.
      Тусклое местоположение = Array.FindIndex (arr, Function (x) x = "zzz")

      'Создайте массивы.
      Dim arr1 (расположение - 1) как строка
      Dim arr2 (arr.GetUpperBound (0) - расположение - 1) как строка
      
      'Заполните два массива.
      Array.Copy (arr, 0, arr1, 0, местоположение)
      Array.Copy (arr, location + 1, arr2, 0, arr.GetUpperBound (0) - местоположение)
   Конец подписки
Конечный модуль

  

Объединение массивов

Вы также можете объединить несколько массивов в один больший массив.Для этого вы также используете метод Array.Copy.

Примечание

В этом разделе не обсуждается объединение массива строк в одну строку. Для получения информации о присоединении к строковому массиву см. Метод String.Join.

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

  • Используйте оператор ReDim Preserve для динамического расширения массива перед добавлением в него новых элементов.Это самый простой метод, но он может привести к снижению производительности и чрезмерному потреблению памяти при копировании больших массивов.
  • Рассчитайте общее количество элементов, необходимых для нового большого массива, затем добавьте к нему элементы каждого исходного массива.

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

  Импорт System.Collections.Generic
Импортирует System.Threading.Tasks

Пример модуля
   Публичная подпрограмма Main ()
      Заменить задачи как новый список (Of Task (Of Integer ()))
      'Создайте четыре массива.Для ctr = от 0 до 3
         Значение затемнения = ctr
         tasks.Add (Task.Run (Функция ()
                               Dim arr (9) как целое число
                               Для ndx = 0 Для arr.GetUpperBound (0)
                                  arr (ndx) = значение
                               Следующий
                               Возвращение arr
                            Конец функции))
       Следующий
       Task.WaitAll (tasks.ToArray ())
       'Подсчитайте количество элементов во всех массивах.
       Тусклые элементы = 0
       Для каждой задачи В задачах
          элементы + = задача.Результат.Длина
       Следующий
       Dim newArray (elements - 1) как целое число
       Тусклый индекс = 0
       Для каждой задачи В задачах
          Dim n = task.Result.Length
          Array.Copy (task.Result, 0, newArray, index, n)
          индекс + = n
       Следующий
      Console.WriteLine ($ "Новый массив содержит {newArray.Length} элементов.")
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
«В новом массиве 40 элементов.

  

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

  Импорт System.Collections.Generic
Импортирует System.Threading.Tasks

Пример модуля
   Публичная подпрограмма Main ()
      Заменить задачи как новый список (Of Task (Of Integer ()))
      'Создайте четыре массива.
      Для ctr = от 0 до 3
         Значение затемнения = ctr
         tasks.Add (Task.Run (Функция ()
                               Dim arr (9) как целое число
                               Для ndx = 0 Для arr.GetUpperBound (0)
                                  arr (ndx) = значение
                               Следующий
                               Возвращение arr
                            Конец функции))
       Следующий
       Задача.WaitAll (tasks.ToArray ())

       'Измерьте размер целевого массива и скопируйте в него каждый элемент каждого исходного массива.
       Dim newArray () As Integer = {}
       'Определите следующую позицию для копирования в newArray.
       Тусклый индекс = 0
       Для каждой задачи В задачах
          Dim n = Task.Result.Length
          ReDim Preserve newArray (newArray.GetUpperBound (0) + n)
          Array.Copy (task.Result, 0, newArray, index, n)
          индекс + = n
       Следующий
      Console.WriteLine ($ "Новый массив содержит {newArray.Length} элементов. ")
   Конец подписки
Конечный модуль
'В примере отображается следующий вывод:
«В новом массиве 40 элементов.

  

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

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

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

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

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

Для получения дополнительной информации о коллекциях см. Коллекции.

См. Также

Основы работы с массивами

Основы работы с массивами

Определение

Массив — это индексированная коллекция элементов данных одного типа.
1) Индексирован. означает, что элементы массива пронумерованы. (начиная с 0).
2) Ограничение того же типа является важным, потому что массивы хранятся в последовательных ячейках памяти. Каждая ячейка должны быть одного типа (и, следовательно, одного размера).

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

Объявление массива похоже на форму обычного объявления (typeName variableName), но мы добавляем размер:
    typeName variableName  [ размер ];
 

Объявляет массив с указанным размером , с именем variableName , типа имя типа .Массив проиндексирован с 0 к размер-1 . Размер (в скобках) должен быть целочисленным литералом или постоянная переменная. Компилятор использует размер, чтобы определить, сколько места выделить (т.е. сколько байтов).

Примеры:

  int list [30]; // массив из 30 целых чисел
  имя символа [20]; // массив из 20 символов
  двойные числа [50]; // массив из 50 знаков после запятой
  int table [5] [10]; // двумерный массив целых чисел
 

Последний пример иллюстрирует двумерный массив (который мы часто нравится думать о таблице).Обычно мы думаем о первом размере как строки, а второй как столбцы, но на самом деле это не имеет значения, если как вы последовательны! Итак, мы могли подумать о последнем объявлении например, в виде таблицы с 5 строками и 10 столбцами.

Инициализация массивов:

С обычными переменными мы можем объявить в одной строке, а затем инициализировать следующий:
  int x;
  х = 0;
 

Или мы могли бы просто инициализировать переменную в объявлении сам:

  int x = 0;
 

Можем ли мы сделать то же самое с массивами? Да, для встраиваемых типов.Просто перечислите массив значения (литералы) в заданной нотации {} после объявления. Вот некоторые примеры:

  int list [4] = {2, 4, 6, 8};
  символьные буквы [5] = {'a', 'e', ​​'i', 'o', 'u'};
  двойные числа [3] = {3,45, 2,39, 9,1};
  int table [3] [2] = {{2, 5}, {3,1}, {4,9}};
 

Струны в стиле C

Массивы типа char — особые случаи.
  • Мы используем строк часто, но нет встроенного строкового типа на языке
  • Строка в стиле C реализована как массив типа char, который заканчивается специальным символом, называемым «нуль» персонаж».
    • Нулевой символ имеет значение ASCII 0
    • Нулевой символ может быть записан как литерал в коде следующим образом: ‘\ 0’
  • Каждый строковый литерал (что-то в двойных кавычках) неявно содержит нулевой символ в конце

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

  char name [7] = "Джонни";
 

Обратите внимание, что это будет эквивалентно:

  char name [7] = {'J', 'o', 'h', 'n', 'n', 'y', '\ 0'};
 

Варианты инициализации

Объявления массивов должны содержать информацию о размер массива. Можно не указывать размер [] в объявлении до тех пор, пока вы инициализируете встроенный массив, в этом случае массив делается достаточно большим, чтобы захватить инициализирован данные.Примеры:

  char name [] = "Джонни"; // размер 7
  int list [] = {1, 3, 5, 7, 9}; // размер 5
 

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

  int list [5] = {1, 2}; // массив: {1, 2, 0, 0, 0}
  int nums [3] = {1, 2, 3, 4}; // незаконное объявление.
 

Примечание. Используя инициализаторы в объявлении, как в приведенных выше примерах, является вероятно, будет не так желательно с очень большими массивами.
Другой распространенный способ инициализации массива — с помощью цикла для :
В этом примере массив numList инициализируется как {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}.

  int numList [10];
  int i;
  для (i = 0; i

 

Использование массивов:

Как только ваши массивы объявлены, вы получаете доступ к элементам в массиве с помощью имя массива и номер индекса в скобках []. Если массив объявляется как: typeName varName [size] , затем элемент с индексом n обозначается как varName [n] .Примеры:
  int x, список [5]; // объявление
  двойные числа [10]; // объявление

  список [3] = 6; // присваиваем значение 6 элементу массива с индексом 3
  cout

 

Однако было бы нецелесообразно использовать индекс массива, за пределами допустимых индексов массива:

  список [5] = 10; // плохой оператор, так как ваши действительные индексы 0-4.
 

Однако синтаксически приведенное выше утверждение законно . Это работа программиста - следить за тем, чтобы индексы за границами не использовались.Не рассчитывайте, что компилятор проверит это за вас - он не будет!

Копирование массивов:

Если у нас есть эти два массива, как нам скопировать содержимое list2 в список1?
  int list1 [5];
  int list2 [5] = {3, 5, 7, 9, 11};
 

С переменными мы используем оператор присваивания, так что это будет естественная тенденция - но это неправильно!

  список1 = список2; // это НЕ копирует содержимое массива
 

Мы должны копировать между массивами поэлементно. для петли делает это легко:

  для (int i = 0; i
 

Простой ввод / вывод со строками:

В особом случае строк (массивы символов с завершающим нулем) они можно использовать как обычные массивы. Доступ к одному элементу массива означает доступ к одному персонажу.
  символ приветствия [] = "Привет";
  char word1 [20];

  cout << приветствие [1]; // печатает букву 'e'
  cout << приветствие [4]; // печатает букву 'о'
 

Строки также могут выводиться и вводиться целиком со стандартным объекты ввода и вывода (cin и cout):
Следующая строка выводит слово «Hello»:

  cout << приветствие;
 
Будьте осторожны, только использует это в массивах символов, которые используются как Струны в стиле С.(Это означает, что только если нулевой символ присутствует как терминатор).

Следующая строка позволяет ввести слово (до 19 символов и завершающий нулевой символ) с клавиатуры, который хранится в массив word1:

  cin >> word1;
 

Символы читаются с клавиатуры до первого «пробела» (пробел, табуляция, новая строка и т. д.) встречается символ. Вход сохраняется в массиве символов, и нулевой символ автоматически добавлено.


Примеры

Массивы - QB64 Wiki

Что такое массивы?

Массивы - это просто переменные с несколькими элементами, каждый из которых может хранить данные в памяти. Для обозначения определенного элемента целые числа обозначают позицию значения в памяти. Не позволяйте разговорам о памяти пугать вас! Basic выполняет всю работу за вас, просто используя простые команды в этом руководстве. Кроме того, вы уже использовали память с тех пор, как создали свою первую переменную!


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

СТРОКА = 1 байт на символ
INTEGER = 2 байта (целые числа со знаком от -32768 до 32767)
LONG = 4 байта (целые числа со знаком от -2147483648 до 2147483647)
SINGLE = 4 байта (до 7 цифр с плавающей запятой)
DOUBLE = 8 байтов (до 15 цифр с плавающей запятой)
_BIT * 8 1 или 0)
_BYTE = 1 байт (целые числа со знаком от -128 до 127)
_INTEGER64 = 8 байт (значения со знаком от -9223372036854775808 до 9223372036854775807
_FLOAT = 10 байт (лучше, чем двойная точность)


В то время как QBasic использует значения со знаком QB64 может использовать значения со знаком или _UNSIGNED для переменных _BITEG, _BYTEON, _BYTEON, _UNSIGNED для _BITEG, _BYTEON, _BYTEON, переменных значения типа.

Тип переменной массива должен быть определен при создании массива. Если тип не используется, тип по умолчанию - SINGLE.

Return to Top

Когда мне нужен массив?

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

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

Единственный недостаток состоит в том, что данные теряются при завершении программы, но данные массива могут быть постоянно сохранены в файлах, когда вы хотите сохранить данные. Все, что вам нужно, это простой цикл для последовательной передачи данных или сохранения всего массива в файл BINARY, используя QB64 с простым оператором PUT.Вы также можете получить данные массива с помощью одного GET.

Return to Top

Создание переменных массива

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

Насколько хорошо вы умеете считать с нуля? Это может показаться простым вопросом, но подумайте об этом. Сколько у нас было бы элементов, если бы они были пронумерованы от 0 до 10? Если вы сказали 11, значит, вы были правы.У некоторых людей возникают проблемы с подсчетом, когда задействован 0, поэтому в Basic есть возможность разрешить всем массивам начинаться с 1.


OPTION BASE 1 приведет к тому, что все измерения массива будут начинаться с 1, OPTION BASE 0 приведет к тому, что все измерения начнутся с 0. По умолчанию, когда используется только максимальный размер массива, равен 0. Используйте любой вариант, который вам удобен.


Массивы в QuickBASIC 4.5 и QBASIC ограничены 32767 элементами, а массивы в QB64 ограничены 2147483647 элементами (более 2 миллиардов).Когда будет реализована 64-битная версия QB64, 9223372036854775807 элементов будут пределом (но только в 64-битных системах).


DIM резервирует имя массива, тип переменной и количество элементов в памяти перед использованием массива. DIM резервирует СТАТИЧЕСКИЙ (неизменяемый) массив, если только метакоманда $ DYNAMIC (изменяемая) не используется при запуске программы или REDIM не использовался для измерения массива изначально.


Пример 1: Измеряет массив с именем «Массив», который может содержать 101 целочисленное значение, включая элемент 0.

Массив DIM (100) КАК ЦЕЛОЕ

Массив начинается с элемента 0, если он не изменен с помощью OPTION BASE 1 (который может установить начало с 1), вы также можете определить начальную и конечную области с помощью DIMensioning в пределах диапазона.


РАЗМЕРЫ с диапазоном значений возможно также при использовании ТО между минимальным и максимальным элементами. Массивы могут начинаться и заканчиваться любым значением элемента (индекса) до 32767. QB64 допускает больший размер массива!

Пример 2: измеряет массив Integer, который может содержать 100 значений с индексами от 1 до 100.

DIM Массив% (от 1 до 100)

Примечание: Тип массива также может быть обозначен суффиксами переменных, поскольку% обозначает целые числа выше.


REDIM можно использовать для изменения размеров динамического массива. Любая информация, содержащаяся в массиве до REDIM, будет потеряна ... однако. Чтобы использовать REDIM, переменная должна быть изначально рассчитана с помощью REDIM, или метакоманда $ DYNAMIC должна быть размещена в верхней части программы.

Пример 3:

ОПЦИЯ БАЗА 1 'размещается перед измерением размеров любых массивов REDIM Array $ (1000) 'REDIM создает динамический массив


QB64 имеет действие REDIM _PRESERVE, которое можно использовать в операторе REDIM для сохранения информации о данных в массиве.


Пример 4: REDIM без действия _PRESERVE стирает содержимое массива

REM $ DYNAMIC Массив DIM (20) массив (10) = 24 PRINT массив (10) REDIM _PRESERVE массив (30) PRINT массив (10) РЕДИМ массив (10) PRINT массив (10)

24 24 0


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


Пример 5: Изменение начального номера индекса с помощью действия _PRESERVE перемещает данные.

REDIM Массив $ (от 1 до 50) Array $ (1) = "Я номер один!" Массив $ (50) = "Мне 50 ..." REDIM _PRESERVE Массив $ (от 51 до 100) PRINT Array $ (51) 'отображает данные нового начального индекса PRINT Array $ (100) 'отображает новые конечные данные

Я номер один! Мне 50 ...

Пример 6: Адрес сегмента памяти массива определяется в DEF SEG.

DEF SEG = VARSEG (массив (0)) offset = VARPTR (array (0)) 'программируемый элемент смещения

ПРИМЕЧАНИЕ: Если используется ОПЦИЯ БАЗА 1, измените 0 на 1.Индекс начала массива может быть изменен, когда в массиве индексируются другие данные.

Return to Top

Многомерные массивы

Для создания таблиц значений можно использовать несколько измерений. QuickBASIC может использовать до 60 измерений. В QB64 количество возможных измерений зависит от вашей системной памяти (намного больше, чем 60 измерений). Данные массива можно сохранять и восстанавливать с помощью файловых данных.

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

ДВУХМЕРНЫЕ ТАБЛИЦЫ МАССИВОВ Настройка базы данных продаж автомобилей: продажи за каждый месяц, представленные в виде массива.DIM Vehicle% (12, 4) 'Vehicle% (месяц%, тип%) Янв фев мар апр май июн июл авг сен окт ноя дек 1 2 3 4 5 6 7 8 9 10 11 12 ← Индекс по месяцам Обозначение типа ↓ --------------------------------------------- - Автомобили 1: 5 10 15 20 30 19 17 12 24 20 33 30 Грузовые автомобили 2: 3 8 7 10 15 9 11 8 15 10 16 11 Фургоны 3: 4 6 8 9 7 10 9 7 9 8 10 7 Внедорожник 4: 10 8 8 5 10 8 6 8 10 11 9 8 Чтобы найти ежемесячные и годовые итоги, вы можете сделать что-то вроде этого: ЗА месяц% = 1 ДО 12 ДЛЯ типа% = от 1 до 4 MonthlySales% = MonthlySales% + Автомобиль% (месяц%, тип%) СЛЕДУЮЩИЙ YearlySales% = YearlySales% + MonthlySales% ПЕЧАТЬ «Ежемесячно =», Ежемесячный% продаж; "Ежегодно ="; YearlySales%; "" INPUT $ (1) 'прекращать просмотр каждый месяц MonthlySales% = 0 продаж за нулевой месяц за следующие месяцы, всего СЛЕДУЮЩИЙ


Пример 7: Создание двумерного массива.Запятая разделяет каждый размерный размер.

DIM Array (12, 10) '2 измерения могут содержать 143 значения данных

Одно измерение может содержать номер месяца, а другое - количество товаров, проданных в 10 категориях.

Пример 8: Размеры с использованием диапазонов индексов.

Массив DIM (от 1 до 12, от 1 до 10) '2 измерения могут содержать 120 значений данных

Return to Top

Работа с элементами массива

После создания массива вы должны что-то в него поместить.Как вы могли заметить, с каждым элементом или индексом связано целое число. Массив (число%) относится только к одному элементу массива независимо от его типа. Массивы МОГУТ иметь элементы с отрицательными номерами!

Вы можете поместить данные в массив несколькими способами. Самый медленный метод - это прямое размещение данных от пользователя. Вы даже можете использовать массив как переменную INPUT. Рекомендуется, чтобы записи ЛЮБОЙ программы пользователя были ограничены текстом, поскольку INPUT выдаст Redo from start error, если пользователь вводит строковое значение, когда требуется числовой ввод.Числовые строковые данные можно преобразовать из строк просто с помощью VAL. Это создает меньше ошибок пользователя! ПРИМЕЧАНИЕ: QB64 не возвращает ошибку «Повторить с начала», поскольку INPUT отслеживает записи.

ДЕЛАТЬ ВВОД "Введите свой возраст:", сколько $ возраст% = VAL (сколько $) ЦИКЛИРОВАТЬ ДО ВОЗРАСТА%> 0 Playerage% (user%) = age% 'сохраняет возраст игроков в индексированный номер игрока PRINT Playerage% (user%) 'вывести элемент массива на экран для проверки ввода user% = user% + 1 'увеличить номер пользователя, когда все данные были введены

Вы можете использовать несколько массивов для хранения имени игрока, рекордов и т. Д.Как только данные помещены в массив, их можно использовать до завершения программы. Затем данные теряются, но вы можете сохранить их в файле перед закрытием программы, просто используя цикл. См. Следующий раздел.


Чтобы передать данные массива в параметр SUB или FUNCTION, скобка пустого элемента передает все элементы, в то время как число передает только один указанный элемент массива.

Индексирование массива

Массивы могут быть настроены для хранения более одного типа данных путем индексации двух или более типов данных.Для этого программист резервирует один набор значений элементов или индексов для каждого типа данных. Тип значений ДОЛЖЕН быть таким же, за исключением случаев использования значения определения TYPE.

Return to Top

Сортировка данных массива

Массивы можно сортировать по номерам или по алфавиту с помощью различных процедур сортировки. Обычно SWAP используется для торговли значениями элементов в порядке убывания или возрастания.

Return to Top

Сохранение данных массива

Поскольку переменные и массивы существуют в памяти, данные теряются при закрытии программы.Чтобы сохранить данные программы, вы должны либо создать постоянное поле DATA, либо сохранить данные в файлы.

В следующий раз, когда программа будет использована, она может ОТКРЫТЬ этот файл и быстро восстановить все данные массива с помощью цикла или QB64 может ПОЛУЧИТЬ данные всего файла одним GET. Используйте LINE INPUT # для установки размеров массива путем подсчета количества строк данных в файле, если вы использовали WRITE CSV (значения, разделенные запятыми) или PRINT # последовательный файл. Количество записей в файле СЛУЧАЙНОГО доступа, определяемом типом или полем, можно найти, разделив размер записи на LOF.Вы можете захотеть немного увеличить массив для новых записей.

Return to Top

Массивы изображений

Массивы

INTEGER используются для хранения информации об изображении при использовании следующих графических процедур: GET, PUT, BSAVE и BLOAD.


Размер массива INTEGER можно оценить, умножив высоту на ширину области изображения. Чтобы найти необходимый фактический размер, вы можете использовать следующую процедуру для обратного отсчета, пока что-то не будет найдено в массиве. В приведенном ниже примере возвращается размер массива, необходимый для создания изображения 20 на 20:

wide & = 20: deep & = 20 'изменяет размеры любой области изображения Массив DIM (широкий & * глубокий &) КАК INTEGER LINE (0, 0) - (широкий & - 1, глубокий & - 1), 12, B 'граница поля - это все, что вам нужно раскрасить.GET (0, 0) - (широкий & - 1, глубокий & - 1), массив (0) ДЛЯ s & = широкий & * глубокий & TO 0 ШАГ -1 IF массив (s &) THEN arrayize & = s &: EXIT FOR СЛЕДУЮЩИЙ ПЕЧАТЬ КОНЕЦ

Примечание: QB64 может получить всю область SCREEN 12 в один массив!


См. Также: Создание масок спрайтов

Return to Top

ОБЩИЕ Массивы

Когда данные массива используются с процедурами SUB или FUNCTION, они могут быть переданы как параметры. При передаче в качестве параметров можно использовать определенный индекс или весь массив.Чтобы указать индекс, массив передается с номером элемента. Если передается весь массив, скобки элементов должны быть пустыми. Пример: SUB SubName (ArrayName () AS INTEGER)


Массивы также могут быть ОБЩИНЫ для всех процедур с помощью DIM SHARED при создании массива. Это позволяет использовать данные массива в основной процедуре и во всех подпроцедурах.


COMMON позволяет совместно использовать данные массива между программными модулями при использовании с CHAIN. Два модуля могут использовать любые значения переменных в списке переменных.В списках могут использоваться разные имена переменных, но типы значений ДОЛЖНЫ быть перечислены в ОДНОМ порядке в обоих модулях.


COMMON SHARED позволяет разделять данные между обоими модулями и процедурами SUB или FUNCTION.


Массивы могут быть созданы внутри процедур SUB или FUNCTION с помощью DIM или REDIM. Также SHARED (без DIM) может использоваться внутри подпроцедуры для обмена переменными данными ТОЛЬКО с главным программным модулем. Другие подпроцедуры не могут ссылаться на данные.Для совместного использования данных массива с другими подпроцедурами можно создать массив FUNCTIONS, который использует внутренние элементы массива в качестве параметра. QB64 может вскоре разрешить подпроцедурам делиться значениями с другими процедурами!


Массивы можно настроить как СТАТИЧЕСКИЕ, чтобы сохранять значения при выходе из подпроцедуры. Значения будут сохраняться до тех пор, пока не будут изменены внутри процедуры. Если процедура создает свой собственный массив, вы можете использовать переменную STATIC True или False, чтобы определить, когда DIM или REDIM массив STATIC, чтобы значения не терялись при каждом вызове.Переменная Ready% ниже DIM-матрица при первом использовании функции:

ФУНКЦИЯ ScanKey% (сканкод%) СТАТИЧЕСКИЙ Готов%, ключевые флаги% () ЕСЛИ НЕ ГОТОВ% THEN REDIM ключевые флаги% (от 0 до 127): Готов% = -1 i% = INP (& H60) 'читать состояния клавиатуры ЕСЛИ (i% AND 128) THEN ключевые флаги% (i% XOR 128) = 0 ЕСЛИ (i% AND 128) = 0 ТОГДА ключевые флаги% (i%) = -1 K $ = INKEY $ ScanKey% = ключевые флаги% (сканкод%) IF scancode% = 0 THEN Ready% = 0 'позволяет программе сбросить все значения на 0 с помощью REDIM КОНЕЧНАЯ ФУНКЦИЯ

Объяснение: Значение STATIC Ready% всегда равно 0 при первом запуске процедуры.NOT ноль делает оператор IF истинным, поэтому массив создается. Значение Ready% затем изменяется на любое значение, кроме нуля, чтобы сделать НЕ Ready% False при повторном вызове процедуры. Ссылка на ФУНКЦИЮ выполняется так же, как на массив. Возвращаемое значение равно 0 или -1, чтобы убедиться, что определенная клавиша была отпущена или нажата соответственно. Статус клавиатуры также обновляется в массиве при каждом вызове. Если переданный скан-код % равен 0 (код сканирования клавиши, который не существует), массив сбрасывается (изменяется размер) при следующем вызове, так как Ready% сбрасывается в ноль.
Return to Top

Сохранение данных

_PRESERVE может сохранять данные, когда REDIM или $ DYNAMIC используются для создания динамических массивов. Текущие данные массива могут быть сохранены при изменении размера элемента массива. Увеличение размера сохранит данные внутри существующих индексов в массиве с измененным размером. При уменьшении размера сохраняются только существующие значения индексов. ТИП массива и количество измерений массива не могут быть изменены!

REDIM _PRESERVE имя массива (от 1 до 100) Return to Top

См. Также


Навигация:
Справочник по ключевым словам - по алфавиту
Ссылка на ключевое слово - по использованию
Основная вики-страница
Массив

- C64-Wiki

Массив - это группа переменных, имеющих одно и то же имя.Ссылка на конкретную переменную в массиве осуществляется с помощью ее индекса массива . Переменные массива могут быть целочисленного, плавающего или строкового типа.

Примеры переменных массива:

 A (2), A (6), NM $ (8), I% (4,6), X (8,5,5)
 

Как видно, массив может иметь две или более индексных переменных (два или более измерений ). В C64 BASIC. в целом массивы могут иметь до 255 измерений. Общее количество элементов в массиве находится путем умножения максимальных номеров индексов каждого измерения вместе.

Если массив должен содержать более 10 переменных (также известных как элементы , ) или быть многомерным, то необходимо использовать оператор DIM, чтобы выделить память для переменных. Массивы с 10 или менее элементами автоматически включаются в DIM при первом обращении к одному из элементов.

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

Если ввести 9 имен без использования массивов, код мог бы выглядеть следующим образом:

 100 ВВОД «СТУДЕНТ 1»; S1 $
110 ВХОД «СТУДЕНТ 2»; S2 $
120 ВХОД «СТУДЕНТ 3»; S3 $
130 ВХОД «СТУДЕНТ 4»; S4 $
140 ВХОД «СТУДЕНТ 5»; S5 $
150 ВХОД «СТУДЕНТ 6»; S6 $
160 ВХОД "СТУДЕНТ 7"; S7 $
170 ВХОД «СТУДЕНТ 8»; S8 $
180 ВХОД «СТУДЕНТ 9»; S9 $
 

Используя массив строк, тот же код будет следующим:

 100 ДЛЯ I = 1 ДО 9
110 ПЕЧАТЬ «СТУДЕНТ»; I;: INPUT S $ (I)
120 ДАЛЕЕ I
 

Фактически, такое же количество кода будет использовано для ввода 100 или 1000 имен.

Фактически, оператор DIM также может использоваться с переменной, что делает код, использующий массивы, очень гибким (хотя массивы можно DIMensioned только один раз). Следующий код был бы невозможен без использования массивов:

100 ВВОД «СКОЛЬКО СТУДЕНТОВ»; N: DIM S $ (N)
110 ДЛЯ I = 1 К N
120 ПЕЧАТЬ «СТУДЕНТ»; I;: INPUT S $ (I)
130 ДАЛЕЕ I
 

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

Возможность ссылаться на элемент массива с такими операторами, как

 A (A (X)) или A (2 * N-3 * A (I))
 

- чрезвычайно мощный и гибкий инструмент для программиста.

Раздел Связанные списки показывает, как массивы могут использоваться для указания на массивы.

Массивы

- визуальное представление для начинающих

Познакомьтесь со структурами данных, которые вы используете каждый день.

👋 Добро пожаловать! Давайте начнем с жизненно важного контекста.Позвольте мне спросить вас:
✅ Слушаете ли вы музыку на своем смартфоне?
✅ Ведете ли вы список контактов в телефоне?
✅ Вы когда-нибудь видели таблицу лидеров во время соревнований?

Если вы ответили «да» на любой из этих вопросов, то почти наверняка вы использовали массивы и даже не знали об этом! 😃 Массивы - это очень мощные структуры данных, в которых хранится списков элементов. У них бесконечное количество приложений. Они очень важны в мире информатики.

Из этой статьи вы узнаете плюсы и минусы массивов, их структуру, операции и варианты использования.

Начнем! 👍

🔎 Подробное описание базовой структуры массивов

Чтобы понять, как они работают, очень полезно визуализировать память вашего компьютера в виде сетки, как показано ниже. Каждая часть информации хранится в одном из тех маленьких элементов (квадратов), которые составляют сетку.

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

О массивах можно думать так:

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

Отлично, правда? Давайте узнаем, как это работает за кулисами! 😃

📚 Классификация

Массивы классифицируются как однородных структур данных , потому что они хранят элементов одного типа .

Они могут хранить числа, строки, логические значения (истина и ложь), символы, объекты и так далее. Но , как только вы определите тип значений, которые будет хранить ваш массив, все его элементы должны быть того же типа. Вы не можете «смешивать» разные типы данных.

👀 Чтение ценностей - волшебство начинается!

Потрясающая сила массивов обеспечивается их эффективностью для доступа к значениям . Это достигается благодаря сетчатой ​​структуре. Давайте посмотрим на это подробнее.🔍

При создании массива вы:
- назначаете его переменной. 👈
- Определите тип элементов, которые он будет хранить. 🎈
- Определите его размер (максимальное количество элементов). 📚

💡 Примечание: Имя, которое вы назначаете этой переменной, очень важно, потому что вы будете использовать его позже в своем коде для доступа к значениям и для изменения массива.

Но как вы можете сказать компьютеру, к какому именно значению вы хотите получить доступ? Здесь индексы играют жизненно важную роль!

1️⃣ Индексы

Вы используете так называемый «индекс» («индексы» во множественном числе) для доступа к значению в массиве.Это число, обозначающее место, где хранится значение.

Как вы можете видеть на диаграмме ниже, первый элемент в массиве упоминается с использованием индекса 0. По мере продвижения вправо индекс увеличивается на единицу для каждого места в памяти.

💡 Примечание: Я знаю, что сначала кажется странным начинать отсчет с 0 вместо 1, но это называется нумерацией с нуля. Это очень распространено в информатике.

Общий синтаксис для доступа к элементу: []

Например:
Если ваш массив хранится в переменной myArray и вы хотите получить доступ к первому элементу (с индексом 0), вы должны использовать myArray [0]

2️⃣ Память

Теперь, когда вы знаете, как получить доступ к значениям, давайте посмотрим, как массивы хранятся в памяти вашего компьютера. Когда вы определяете размер массива, все это пространство в памяти «зарезервировано» с этого момента на для будущих значений, которые вы, возможно, захотите вставить.

💡 Примечание: Если вы не заполните массив значениями, это пространство будет зарезервировано и пусто до тех пор, пока вы не заполните его.

Например:
Допустим, вы определяете массив размером 5, но вставляете только одно значение. Все оставшееся пространство будет пустым и «зарезервированным» в памяти в ожидании будущих назначений.

Это ключевой момент, поскольку массивы чрезвычайно эффективны при доступе к значениям, поскольку все элементы хранятся в непрерывных пространствах памяти. Таким образом, компьютер точно знает, где искать запрошенную информацию.

Но… у этого есть обратная сторона 😞 потому что это неэффективно с точки зрения памяти . Вы резервируете память для будущих операций, которые могут не произойти. Поэтому массивы рекомендуются в ситуациях, когда вы заранее знаете, сколько элементов вы собираетесь хранить.

🔧 Операции - за кадром!

Теперь, когда вы знаете, что такое массивы, когда они используются, и как они хранят элементы, мы погрузимся в их операции, такие как вставка и удаление.

1️⃣ Вставка - Добро пожаловать!

Допустим, у нас есть массив размером 6, но все еще есть пустое место. Мы хотим вставить элемент «е» в начало массива (индекс 0), но это место уже занимает элемент «а». Что нам делать?

Чтобы вставить в массивы , мы перемещаем все элементы, расположенные справа от места вставки, на один индекс вправо.Элемент «a» теперь будет иметь индекс 1, элемент «b» будет иметь индекс 2 и так далее…

💡 Примечание: Вам нужно будет создать переменную, чтобы отслеживать последний индекс, который содержит элементы. На диаграмме выше перед вставкой массив заполняется до индекса 4. Таким образом, вы можете определить, заполнен ли массив и какой индекс следует использовать для вставки элемента в конце.

После этого наш элемент успешно вставлен. 👏

⚠️ Погодите! Что произойдет, если массив заполнен?

Как вы думаете, что произойдет, если массив заполнится и вы попытаетесь вставить элемент? 😱

В этом случае вам необходимо создать новый массив большего размера и вручную скопировать все элементы в этот новый массив. Операция стоит очень дорого по времени. Представьте, что бы произошло, если бы у вас был массив с миллионами элементов! Это может занять очень много времени. ⏳

💡 Примечание: Единственное исключение из этого правила, когда вставка выполняется очень быстро, - это когда вы вставляете элемент на конце массива (по индексу, расположенному справа от последнего элемент), и еще есть свободное место. Это делается за постоянное время O (1).

2️⃣ Удаление - пока, пока!

Теперь предположим, что вы хотите удалить элемент из массива.

Для поддержания эффективности произвольного доступа (возможность чрезвычайно быстрого доступа к массиву через индекс) элементы должны храниться в смежных областях памяти. Вы не можете просто удалить элемент и оставить это место пустым.

Вам следует переместить элементы, следующие за элементом, который вы хотите удалить, на один индекс влево.

И, наконец, у вас есть результирующий массив 👇.Как видите, «b» успешно удалена.

💡 Примечание: Удаление очень эффективно при удалении последнего элемента . Поскольку вам нужно создать переменную для отслеживания последнего индекса, содержащего элементы (на диаграмме выше, индекс 3), вы можете напрямую удалить этот элемент с помощью индекса.

3️⃣ Поиск элемента

У вас есть три варианта поиска элемента в массиве:

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

👋 Вкратце…

  • Массивы - это чрезвычайно мощные структуры данных , в которых хранятся элементы одного типа.Тип элементов и размер массива фиксируются и определяются при его создании.
  • Память выделяется сразу после создания массива и пуста, пока вы не присвоите значения.
  • Их элементов расположены в смежных местах в памяти , поэтому к ним можно получить очень эффективный доступ (произвольный доступ, O (1) = постоянное время) с использованием индексов .
  • Индексы начинаются с 0 , а не с 1, как мы привыкли.
  • При вставке элементов в начало или в середину массива элементы перемещаются вправо.Если массив заполнен, создается новый массив большего размера (что не очень эффективно). Вставка в конец массива очень эффективна, постоянное время O (1).
  • Удаление элементов из начала или из середины массива включает перемещение всех элементов влево, чтобы не оставлять пустое место в памяти. Это гарантирует, что элементы хранятся в непрерывных пространствах памяти. Удаление в конце массива очень эффективно, потому что вы удаляете только последний элемент.
  • Чтобы найти элемент , вам нужно проверить весь массив, пока не найдете его. Если данные отсортированы, вы можете использовать такие алгоритмы, как двоичный поиск, для оптимизации процесса.
«Учись у вчерашнего дня, живи сегодняшним днем, надейся на завтра. Главное - не переставать задавать вопросы ».

- Альберт Эйнштейн

👋 Спасибо!

Очень надеюсь, что вам понравилась моя статья. ❤️
Следуйте за мной в Твиттере , чтобы найти больше подобных статей.😃

VB.Net Массивы: Строка, Динамическая с ПРИМЕРАМИ

Что такое массив?

Массив - это структура данных, используемая для хранения элементов одного типа данных. Элементы упорядочиваются последовательно, первый элемент имеет индекс 0, а последний элемент - индекс n-1, где n - общее количество элементов в массиве.

В этом руководстве вы узнаете:

Как объявить и инициализировать массив

В VB.NET массивы объявляются с помощью оператора Dim.Например:

Dim myData () как целое число
 

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

Dim myData (10) как строка
 

Мы определили массив с именем myData для хранения 10 строк.

Мы можем инициализировать массивы во время их объявления. Например:

Dim myData () как целое число = {11, 12, 22, 7, 47, 32}
 

Мы объявили массив myData и добавили в него 6 целочисленных элементов.То же самое можно сделать и для струн:

Dim student () As String = {"John", "Alice", "Antony", "Gloria", "jayden"}
 

Мы создали массив с именем student и добавили к нему 5 имен.

Массивы фиксированного размера

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

Затемнить студентов (от 0 до 2) как строку
      
студенты (0) = "Джон"
студенты (1) = "Алиса"
студенты (2) = "Антоний"
 

Мы начали с объявления массива строк с именем student.От 0 до 2 объявляет, что в массиве будут храниться элементы от индекса 0 до индекса 2, что означает, что всего у нас будет 3 элемента.

Чтобы добавить элементы в массив, мы использовали имя массива и указали индекс, по которому элемент будет сохранен. Например, имя John будет сохранено в индексе 0 массива, что означает, что оно сформирует первый элемент массива. Антоний будет последним элементом массива.

Динамические массивы

Это массив, который может содержать любое количество элементов.Размер массива может увеличиваться в любой момент. Это означает, что вы можете добавлять новые элементы в массив в любое время. Чтобы продемонстрировать это, давайте сначала определим массив целых чисел:

Dim nums () как целое число
 

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

ReDim nums (1)
число (0) = 12
число (1) = 23
 

В нашем массиве теперь два элемента в индексах 0 и 1.Нам нужно добавить к нему третий элемент с индексом 3, сохранив два элемента, которые у него уже есть. Сделать это можно так:

ReDim Preserve число (2)
число (2) = 35
 

Теперь массив состоит из трех элементов.

Получение содержимого массива

Получение означает доступ к элементам массива. Для доступа к элементу массива мы используем его индекс. Продемонстрируем это на примере.

Шаг 1) Начните с создания нового консольного приложения.

Шаг 2) Добавьте в заявку следующий код:

Модуль Module1
    Подчиненный главный ()

       Затемнить студентов (от 0 до 2) как строку

        студенты (0) = "Джон"

        студенты (1) = "Алиса"

        студенты (2) = "Антоний"

        Console.WriteLine ("Первый учащийся - {0}", учащиеся (0))

        Console.WriteLine ("Второй учащийся - {0}", учащиеся (1))

        Console.WriteLine ("Третий ученик - {0}", ученики (2))


        Приставка.ReadKey ()

    Конец подписки

Конечный модуль
 

Шаг 3) Запустите код, нажав кнопку «Пуск» на панели инструментов. Вы получите следующее окно:

Мы использовали следующий код:

Объяснение кода:

  1. Создание модуля с именем Module1.
  2. Создание основной подпроцедуры.
  3. Создание массива с именем student для хранения строковых элементов. В массиве будут храниться элементы от индекса 0 до индекса 2, что означает, что в нем будет всего 3 элемента.
  4. Добавление имени John в качестве первого элемента массива, то есть John, сохраненного в индексе 0.
  5. Добавление имени Alice в качестве второго элемента массива, то есть Алиса, сохраненного в индексе 1.
  6. Добавление имени назовите Antony в качестве третьего элемента массива, то есть Antony, сохраненного в индексе 2.
  7. Печать некоторого текста и элемента, хранящегося в индексе 0 массива student на консоли. Студенты (0) помогают нам получить доступ к элементу с индексом 0 массива с именем student.
  8. Печать некоторого текста и элемента, хранящегося в индексе 1 массива студентов на консоли. Студенты (1) помогают нам получить доступ к элементу в индексе 1 массива с именем student.
  9. Печать некоторого текста и элемента, хранящегося в индексе 2 массива студентов на консоли. Студенты (2) помогают нам получить доступ к элементу в индексе 2 массива с именем student.
  10. Приостановка окна консоли в ожидании или действия пользователя по его закрытию.
  11. Конец подпроцедуры.
  12. Конец модуля.

Добавление новых элементов в массив

Это произойдет только в том случае, если у вас есть динамический массив. Если вы объявили размерный массив фиксированного размера и он заполнен элементами массива, вы не можете добавлять в него новые элементы. В следующем примере показано, как добавлять новые элементы в динамический массив:

Шаг 1) Начните с создания нового консольного приложения.

Шаг 2) Добавьте в заявку следующий код:

Модуль Module1
    Подчиненный главный ()

        Dim nums () как целое число

        ReDim nums (1)
        число (0) = 12
        число (1) = 23

        Для x = 0 До кол-во.Длина - 1
            Console.WriteLine ("Начальный элемент массива: {0}", nums (x))
        Следующий

        ReDim Preserve число (2)
        число (2) = 35

        Для x = 0 до nums.Length - 1
            Console.WriteLine ("Последний элемент массива: {0}", nums (x))
        Следующий

        Console.ReadKey ()
    Конец подписки

Конечный модуль
 

Шаг 3) Нажмите кнопку «Пуск» на панели инструментов, чтобы запустить код. Вы должны получить следующее окно:

Мы использовали следующий код:

Объяснение кода:

  1. Создание модуля с именем Module1.
  2. Создание основной подпроцедуры.
  3. Создание массива с именем nums для хранения целочисленных значений.
  4. Указывает, что в указанном выше массиве будут храниться два элемента, то есть с индексами 0 и 1, при этом останется место для изменения размера.
  5. Добавление элемента 12 в индекс 0 массивов nums.
  6. Добавление элемента 23 в индекс 1 массива nums.
  7. Использование цикла for для создания переменной x, которая помогает нам выполнять итерацию от первого до последнего элементов массива nums.Обратите внимание, что теперь в массиве два элемента: 12 и 23.
  8. Печать текста и элементов массива на консоли.
  9. Завершение цикла for и переход к следующей части кода.
  10. Измените размер массива, чтобы разрешить элементы с индексами от 0 до 2. Теперь он сможет хранить 3 элемента, а не 2. Ключевое слово Preserve помогает нам поддерживать текущие элементы массива, то есть 12 и 23.
  11. Добавление элемента 35 в индекс 2 массива. Теперь в массиве три элемента: 12, 23 и 35.
  12. Использование цикла for для создания переменной x, которая помогает нам выполнять итерацию от первого до последнего элементов массива nums. Обратите внимание, что теперь массив состоит из трех элементов: 12, 23 и 35.
  13. Печать текста и элементов массива на консоли.
  14. Завершение цикла for и переход к следующей части кода.
  15. Приостановить окно консоли, ожидая, пока пользователь закроет его.
  16. Конец подпроцедуры.
  17. Конец модуля.

Удаление массива

Рекомендуется стереть массив после того, как вы закончите с ним, в основном, когда вы имеете дело с динамическим массивом.Это поможет вам освободить место в памяти.

Чтобы удалить массив, вам просто нужно вызвать оператор Erase, за которым следует имя массива. Например:

Dim nums (1) как целое число
        число (0) = 12
        число (1) = 23
Стереть числа
 

Мы объявили массив целых чисел с именем nums и добавили к нему два элемента. Оператор Erase nums стирает массив.

Функция разделения

Функция разделения, предоставляемая Visual Basic.NET помогает нам разбить строку на части и сохранить их в массиве. В следующем примере показано, как использовать эту функцию:

Шаг 1) Создайте новое консольное приложение.

Шаг 2) Добавьте в заявку следующий код:

Модуль Module1
    Подчиненный главный ()

        Dim myarray () как строка
        Dim guru99 как строка
        Dim x As Integer

        guru99 = "Добро пожаловать, Guru99"
        myarray = Разделить (guru99, ",")

        Для x = LBound (myarray) To UBound (myarray)

            Приставка.WriteLine (myarray (x))

        Следующий

        Console.ReadKey ()
    Конец подписки

Конечный модуль
 

Шаг 3) Запустите код, нажав кнопку «Пуск» на панели инструментов. Вы должны получить следующее окно:

Мы использовали следующий код:

Объяснение кода:

  1. Создание модуля с именем Module1.
  2. Запуск основной подпроцедуры.
  3. Создание массива с именем myarray для хранения строковых значений.
  4. Создание строковой переменной с именем guru99.
  5. Создание целочисленной переменной с именем x.
  6. Назначение строки переменной guru99.
  7. Разделение указанной выше строки на части и размещение их в массиве с именем myarray. «,» (Запятая) является разделителем, поэтому функция разделения будет использовать его для обозначения конца различных частей строки.
  8. Использование переменной x для перебора массива myarray. LBound и UBound определяют нижнюю и верхнюю границы массива соответственно.
  9. Выводит значения массива myarray на консоль.
  10. Завершение цикла for и

Функция соединения

Функция соединения помогает нам объединить несколько массивов в одну строку. Следующий пример демонстрирует это:

Шаг 1) Начните с создания нового консольного приложения.

Шаг 2) Добавьте в заявку следующий код:

Модуль Module1
    Подчиненный главный ()

        Уменьшить размер учащихся (от 0 до 2) в виде строки

        студенты (0) = "Джон"

        студенты (1) = "Алиса"

        студенты (2) = "Антоний"

        Тусклые одноклассники как строка


        classmates = Присоединяйтесь (студенты, ",")

        Приставка.WriteLine (одноклассники)

        Console.ReadKey ()
    Конец подписки

Конечный модуль
 

Шаг 3) Запустите код, нажав кнопку «Пуск» на панели инструментов:

Мы использовали следующий код:

Объяснение кода:

  1. Создание модуля с именем Module1.
  2. Создание основной подпроцедуры.
  3. Создание массива с именем student для хранения 3 строковых значений.
  4. Добавление имени John в индекс 0 массива.
  5. Добавление имени Алиса в индекс 1 массива.
  6. Добавление имени Антоний в индекс 2 массива.
  7. Определение переменной с именем одноклассники строкового типа данных.
  8. Объединение всех элементов массива student и разделение их с помощью символа (запятая). Результат этой операции будет присвоен переменной одноклассникам.
  9. Печать содержимого переменной одноклассников на консоли.
  10. Приостановка окна консоли в ожидании действия пользователя по его закрытию.
  11. Завершение основной подпроцедуры.
  12. Завершение модуля.

Сводка

  • Массивы используются для хранения элементов данных, принадлежащих к одному типу данных.
  • Динамический массив позволяет пользователю изменять его размер, добавляя в него дополнительные элементы. Вы используете команду ReDim для добавления элементов в существующий массив
  • Размер массива фиксированного размера не может быть изменен.
  • Элементы массива упорядочены с использованием индексов, причем первый элемент имеет индекс 0, а последний элемент - индекс n-1, где n - общее количество элементов массива.
  • Массивы могут быть удалены с помощью функции стирания
  • Вы можете использовать функции разделения и соединения для разделения или присоединения массива строк соответственно

Массивы - - Документация по BASIC Great Cow

О массивах

Массив - это особый тип переменных, который может хранить сразу несколько значений. По сути, это список чисел в каждый из которых может быть рассмотрен индивидуально с помощью «индекса».

Числа могут быть байтами (по умолчанию), длинными, целыми или словами. Индекс - это значение в скобках сразу после имя массива.

Все числа, хранящиеся в массиве, должны быть одного типа. Например, вы не можете хранить байты и слова в одном массиве.

Примеры имен массивов:

Массив / индекс Значение

Рыба (10)

Определение массива, содержащего байты с 10 элементами, называемого Fish

x (5) Как Word

Определение массива, содержащего слова с 5 элементами под названием x

Журнал данных (2)

Второй элемент в массиве с именем DataLog

Список кнопок (температура)

Элемент в массиве ButtonList , выбранный в соответствии с значение в переменной Temp

Определение массива

Используйте команду DIM для определения массива.

 DIM array_title (number_of_elements) [As _type_] 

Количество элементов может быть числом или константой, но не переменной.

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

Присвоение значений массиву

В одной строке кода можно установить несколько элементов байтового массива.Этот короткий пример показывает, как:

 Dim TestVar (10)
    TestVar = 1, 2, 3, 4, 5, 6, 7, 8, 9 

При использовании этого метода элементу 0 массива TestVar будет присвоено количество элементов в списке, которые в этом case - 9. Затем каждый элемент массива будет загружен с соответствующим значением в списке - так в примере TestVar (1) будет установлено значение 1, TestVar (2) - 2 и так далее. Элемент 0 будет установлен только на количество элементов в массиве при использовании этого метод до 48 элементов данных.

Однако это работает только для -байтовых массивов . Для массивов типа integer , word или long каждый элемент должен быть установлен отдельно:

 Dim TestVar (5) Как слово
    TestVar (1) = 20
    TestVar (2) = 50
    TestVar (3) = 60
    TestVar (4) = 80
    TestVar (5) = 100 

Если каждый элемент имеет одинаковое значение, его можно сократить с помощью цикла:

 Dim TestVar (5) As Word
    Для i = от 1 до 5
        TestVar (i) = 0
    Далее 

Длина массива

Элемент 0 не должен использоваться для получения длины массива.Элемент 0 будет согласован только по длине массива, когда массив установлен, как показано выше.

Правильный метод - использовать константу для установки размера массива и использовать константу в вашем коде для получения длины массива.

 #Define ArraySizeConstant 500
    Dim TestVar (ArraySizeConstant)

    SerPrint ArraySizeConstant 'или другое использование 

Использование массивов

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

Максимальный размер массива

Ограничение размера массива зависит от типа микросхемы, объема ОЗУ и количества других переменных, которые вы используете в ваша программа.

Используйте следующую простую программу, чтобы определить максимальный размер массива. Установите CHIP на свое устройство, MAXSCOPE на значение, которое меньше общего объема ОЗУ, и тип данных test_array на тип данных, которые будут храниться в массиве.

Тип данных imaxscope должен быть установлен в соответствии с размером константы MAXSCOPE . Если MAXSCOPE ⇐ 255, imaxscope должен быть байтом. Если MAXSCOPE > 255, imaxscope должно быть словом.

Если массив слишком велик для размещения, компилятор выдаст сообщение об ошибке. Уменьшайте MAXSCOPE, пока сообщение об ошибке не исчезнет. изданный. Наибольшее значение MAXSCOPE без сообщения об ошибке является наибольшим используемым массивом этого типа для этого чипа.

 # ЧИП 12f1571
    #OPTION Явный

    #DEFINE MAXSCOPE 111
    DIM imaxscope как байт
    DIM test_array (MAXSCOPE) как байт


    Для imaxscope = от 0 до MAXSCOPE
      test_array (imaxscope) = imaxscope
    Далее 

Для Atmel AVR, LGT 328p или 18F размеры массива ограничены до 10 000 элементов.

Если достигнут предел памяти, компилятор выдаст сообщение об ошибке.

Максимально используйте доступную память

Использование ОЗУ массива определяется архитектурой типа микросхемы.Максимальное использование доступной памяти определяется размещением массива в доступных банках памяти.

Примером является массив из 6 или 7 байтов, когда есть только 24 байта ОЗУ, а 24 байта разделены по нескольким памяти. банки. Предположим, что в этом примере 18 байтов выделено другим переменным, а всего доступно 29 байтов. An массив из 6 байтов поместится в свободное место в одном банке, а массив из 7 - нет.

Great Cow BASIC в настоящее время не может разбить массив по банкам, поэтому, если в одном банке есть 6 свободных байтов, а в другом - 5, вы не может иметь массив из 7 байтов. Было бы очень сложно сделать это эффективно на 12F / 16F, так как там будет ряд специальных функция регистрируется в середине массива при использовании 12F или 16F. Это ограничение не относится к 16F1 / 18F как линейному адресация упрощает охват банков, поскольку SFR не создают проблемы (как в случае с 12F / 16F).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *