Как в си передать массив в: c++ — Как передать массив в функцию?
Содержание
Как передать массив через HTML форму в PHP
Можно объединить несколько элементов формы и получить их на сервере в виде массива. Это делается с помощью манипуляций с атрибутом name.
Так можно передать ассоциативный массив:
<form>
<input type="text" name="product[name]">
<input type="text" name="product[article]">
<input type="text" name="product[price]">
<input type="submit">
</form>
При отправке формы содержимое $_GET будет таким:
Array
(
[product] => Array
(
[name] => Название
[article] => Артикул
[price] => Цена
)
)
Пример обработчика этой формы:
<?php
if(!empty($_GET['product']))
{
// Можно перебрать все поля
foreach($_GET['product'] as $k => $v)
echo "$k : $v <br>";
// Или обратиться к конкретному полю
echo $_GET['product']['name'];
}
?>
<form>
<input type="text" name="product[name]">
<input type="text" name="product[article]">
<input type="text" name="product[price]">
<input type="submit">
</form>
Разумеется, ключами могут быть и обычные числа. А если нужно, чтобы ключи шли по порядку, можно просто ничего не указывать в квадратных скобках:
<form>
<input type="text" name="values[]">
<input type="text" name="values[]">
<input type="text" name="values[]">
<input type="submit">
</form>
Содержимое $_GET будет таким:
Array
(
[values] => Array
(
[0] => Значение 1
[1] => Значение 2
[2] => Значение 3
)
)
Можно передавать и многомерные массивы, например для редактирования сразу нескольких записей в базе данных:
<form>
<input type="text" name="images[10][title]">
<input type="text" name="images[10][url]">
<input type="text" name="images[11][title]">
<input type="text" name="images[11][url]">
<input type="submit">
</form>
Пример обработчика этой формы:
<?php
if(!empty($_GET['images']))
{
foreach($_GET['images'] as $id => $data)
{
echo "ID: $id, ";
echo "Title: $data[title], ";
echo "URL: $data[url] <br>";
}
}
?>
В одной форме можно указывать обычные поля и массивы вместе:
<form>
<input type="text" name="id">
<input type="text" name="product[name]">
<input type="text" name="images[15][title]">
<input type="submit">
</form>
Как передать массив (7, 3, 3, 3) в подпрограмму fortran? Ru Python
Я написал fortran подпрограмму, используя в python через команду f2py.
Подпрограмма занимает несколько десятков символов (7, 3, 3, 3). Массив представляет собой массив из 7 кубов размером 3x3x3. Я также передаю целые числа 7 и 3 в подпрограмму.
Вот код
subroutine fit(n, m, a) c =================================================================== c ArrayTest.f c =================================================================== cn - number of cubes being passed c cm - edge of cube size c ca(n,m,m,m) - array of shape (n,m,m,m) c c =================================================================== implicit none integer m integer n double precision a(n,m,m,m) end subroutine fit
Это просто, чтобы проверить, могу ли я передать массив. Когда я компилирую и вызываю его из python, я получаю следующую ошибку.
import ArrayTest as AT import numpy as np n = 7 m = 3 a = np.ones((n,m,m,m)) AT.fit(n, m, a)
бросает
ArrayTest.error: (shape(a,0)==n) failed for 1st keyword n: fit:n=3
Я понятия не имею, что происходит. Определение массива в fortran как (m, m, m, m) не вызывает проблем, только когда я пытаюсь определить его из двух целых чисел, что вызывает проблемы, даже если я устанавливаю оба m = n = 3. Как передать массив (7, 3, 3, 3) в подпрограмму fortran?
Взгляните на docstring функции Python, созданной f2py:
fit(a,[n,m]) Wrapper for ``fit``. Parameters ---------- a : input rank-4 array('d') with bounds (n,m,m,m) Other Parameters ---------------- n : input int, optional Default: shape(a,0) m : input int, optional Default: shape(a,1)
f2py признал, что n
и m
описывают форму a
, и поэтому не требуются аргументы для функции Python, так как они могут быть найдены путем проверки формы массива numpy. Таким образом, они являются необязательными вторым и третьим аргументами функции Python:
In [8]: import ArrayTest as AT In [9]: n = 7 In [10]: m = 3 In [11]: a = np.zeros((n, m, m, m)) In [12]: AT.fit(a, n, m) In [13]: AT.fit(a)
Передача аргументов в программу. Урок 19 курса «Основы C»
Бывает, что данные в программу передаются из командной строки при ее вызове. Такие данные называются аргументами командной строки. Выглядит это так, например:
./a.out test.txt ls -lt /home/peter/
Здесь вызываются программы a.out (из текущего каталога) и ls (из одного каталога, указанного в переменной окружения PATH). Первая программа из командной строки получает одно слово — test.txt, вторая — два: -lt и /home/peter/.
Если программа написана на языке C, то при ее запуске управление сразу передается в функцию main()
, следовательно, именно она получает аргументы командной строки, которые присваиваются ее переменным-параметрам.
До этого мы определяли функцию main()
так, как-будто она не принимает никакие параметры и ничего не возвращает. На самом деле в языке C любая функция по-умолчанию (если не определено ничего иного) возвращает целое число. В этом можно убедиться. Если записать код таким образом:
main() { printf("Hi\n"); return 0; }
, то ошибки при компиляции не возникнет (но будет предупреждение). То же самое будет, если записать int main()
. Это доказывает, что функция по-умолчанию возвращает целое число, а не ничто (void
). Хотя то, что возвращает функция всегда можно «переопределить», например, voidmain()
или float main()
.
При вызове программы из командной строки в нее всегда передается пара данных:
- целое число, обозначающее количество слов (элементов, разделенных пробелами) в командной строке при вызове,
- указатель на массив строк, где каждая строка — это отдельное слово из командной строки.
Само имя программы также считается. Например, если вызов выглядит так:
./a.out 12 theme 2
, то первый аргумент программы имеет значение 4, а массив строк определяется как {«./a.out», «12», «theme», «2»}.
Обратите внимание на терминологию, есть всего два аргумента программы (число и массив), но сколько угодно аргументов командной строки. Аргументы командной строки «преобразуются» в аргументы программы (в аргументы функции main()
).
Эти данные (число и указатель) передаются в программу даже тогда, когда она просто вызывается по имени без передачи в нее чего-либо: ./a.out. В таком случае первый аргумент имеет значение 1, а второй указывает на массив, состоящий всего из одной строки {«./a.out»}.
То, что в программу передаются данные, вовсе не означает, что функция main()
должна их принимать. Если функция main()
определена без параметров, то получить доступ к аргументам командной строки невозможно. Хотя ничего вам не мешает их передавать. Ошибки не возникнет.
Чтобы получить доступ к переданным в программу данным, их необходимо присвоить переменным. Поскольку аргументы сразу передаются в main()
, то ее заголовок должен выглядеть таким образом:
int main(int n, char *arr[])
В первой переменной (n) содержится количество слов, а во второй — указатель на массив строк. Часто второй параметр записывают в виде **arr
. Однако это то же самое. Вспомним, что сам массив строк, содержит в качестве своих элементов указатели на строки. А в функцию мы передаем указатель на первый элемент массива. Получается, что передаем указатель на указатель, т.е. **arr
.
Напишите такую программу:
#include <stdio.h> int main(int argc, char **argv) { int i; printf("%d\n", argc); for (i=0; i < argc; i++) puts(argv[i]); }
Она выводит количество слов в командной строке при ее вызове и каждое слово с новой строки. Вызовите ее без аргументов командной строки и с аргументами.
В программе мы использовали переменные-параметры argc и argv. Принято использовать именно такие имена, но на самом деле они могут быть любыми. Лучше придерживаться этого стандарта, чтобы ваши программы были более понятны не только вам, но и другим программистам.
Практическое значение передачи данных в программу
Если у вас есть опыт работы в командной строке GNU/Linux, вы знаете, что у большинства команд есть ключи и аргументы. Например, при просмотре содержимого каталогов, копировании, перемещении в качестве аргументов указываются объекты файловой системы, над которыми выполняется команда. Особенности ее выполнения определяются с помощью ключей. Например, в команде
cp -r ../les_1 ../les_101
cp — это имя команды, -r — ключ, а ../les_1 и ../les_101 — аргументы команды.
Нередко в программы при их запуске передаются адреса файлов и «модификаторы» (это ключи) процесса выполнения программы.
Напишем программу, которая открывает указанные пользователем в командной строке файлы на запись или добавление и записывает (добавляет) туда одну и туже информацию, которую пользователь вводит с клавиатуры в процессе выполнения программы:
#include <stdio.h> #include <string.h> int main (int argc, char **argv) { int i, ch; FILE *f[5]; if (argc < 3 || argc > 7) { puts("Неверное количество параметров"); return 1; } if (strcmp(argv[1], "-w") != 0 && strcmp(argv[1], "-a") != 0) { puts("Первый параметр -w или -a"); return 2; } for (i=0; i < argc-2; i++){ f[i] = fopen(argv[i+2], argv[1]+1); if (f[i] == NULL) { printf("Файл %s нельзя открыть\n", argv[i+2]); return 3; } } while ((ch = getchar()) != EOF) for (i=0; i < argc-2; i++) putc(ch,f[i]); for (i=0; i < argc-2; i++) fclose(f[i]); return 0; }
Пояснения к коду:
- Создается массив из пяти файловых указателей. Следовательно можно одновременно открыть не более пяти файлов. Файловый указатель первого файла будет хранится в элементе массива f[0], второго — в f[1] и т.д.
- Проверяется количество аргументов командной строки. Их должно быть не меньше трех, т.к. первый — это имя программы, второй — режим открытия файла, третий — первый или единственный файл, в который будет производится запись. Поскольку программа позволяет открыть только пять файлов, то общее число аргументов командной строки не может быть больше семи. Поэтому если количество аргументов меньше 3 или больше 7, то программа завершается, т.к. оператор
return
приводит к выходу из функции, даже если после него есть еще код. Возвращаемое из функции значение неравное 0, может быть интерпретировано родительским процессом, как сообщение о том, что программа завершилась с ошибкой. - Проверяется корректность второго аргумента командной строки. Если он не равен ни «-w», ни «-a», то условное выражение во втором
if
возвращает 1 (true). Функцияstrcmp()
позволяет сравнивать строки и возвращает 0 в случае их равенства. - В цикле
for
открываются файлы по указанным адресам, которые начинаются с третьего элемента массива argv. Именно поэтому к i прибавляется 2, чтобы получать элементы массива argv, начиная с третьего. Выражениеargc-2
указывает на количество переданных имен файлов; т.к. в argc хранится общее число аргументов командной строки, первые два из которых не являются именами файлов. - Выражение
argv[1]+1
позволяет «вырезать» из строки «-w» (или «-a») подстроку «w» (или «a»), т.к.argv[1]
по сути указатель на первый элемент строки. Прибавляя к указателю единицу, мы смещаем его к следующему элементу массива. - Если файл отрыть не удается, то функция
fopen()
возвращает NULL. В таком случае программа завершается. - Каждый символ, введенный пользователем с клавиатуры, записывается во все открытые файлы.
- В конце файлы закрываются.
Курс с решением части задач:
android-приложение, pdf-версия
За бортом правительства. Почему Курц ушел с поста канцлера Австрии?
Себастьян Курц
© EPA-EFE/CHRISTIAN BRUNA
«Акела промахнулся!» Этой известной фразой по мотивам «Книги джунглей» Редьярда Киплинга можно охарактеризовать правительственный кризис в Австрии вокруг канцлера Себастьяна Курца. Политические оппоненты и либеральная австрийская пресса поспешили без суда признать его «недееспособным» шефом правительства, когда он стал фигурантом расследования о предполагаемых тратах бюджетных средств на улучшение имиджа возглавляемой им консервативной Австрийской народной партии (АНП). Стремление как минимум сохранить собственную партию у руля в коалиционном кабинете министров с «Зелеными» вынудило Курца пожертвовать собой и передать кресло канцлера соратнику и министру иностранных дел Александеру Шалленбергу. Второй раз за два года Курца вытеснили из правительства, но в его случае это определенно не станет концом вожака стаи.
Вынужденный шаг назад
Уход Курца из правительства отчасти предопределили обыски в штаб-квартире его партии, ведомстве федерального канцлера и Министерстве финансов. Они произвели эффект внутриполитического землетрясения из-за подозрения в том, что Курц и его окружение в период 2016–2018 годов могли быть причастны к организации финансирования из госбюджета положительных для его партии соцопросов и публикаций на ресурсах крупнейшего австрийского медиаконцерна Österreich.
На эту тему
Следствие исходит из того, что размер ущерба государству превысил €300 тыс. Порог, при котором в случае доказанного обвинения по делу о злоупотребоении доверием грозит до 10 лет тюрьмы. Хотя в отношении всех подозреваемых действует презумпция невиновности. Именно Курца следствие считает лицом, с одобрения которого были совершены предполагаемые махинации с деньгами австрийских налогоплательщиков. Курц назвал эти обвинения ложными и намерен приложить максимальные усилия для их опровержения.
Не упустившая свой шанс оппозиция успела навязать общественному мнению и средствам массовой информации посыл о необходимости отставки Курца. Этот призыв неожиданно поддержала партия «Зеленые» — партнер Курца по правительственной коалиции. Они публично поставили ультиматум Курцу и для продолжения сотрудничества с консерваторами в кабмине призвали его заменить себя на посту канцлера на человека с безупречной репутацией. В противном случае «Зеленые» могли поддержать оппозиционный вотум недоверия канцлеру в парламенте, за которым мог вообще последовать исход АНП из правительства.
Выборы сейчас невыгодны
Перспектива остаться за бортом власти или объявления досрочных парламентских выборов в случае вотума недоверия совершенно невыгодна для АНП этой осенью в условиях звучащих против ее лидера обвинений. Гипотетически консерваторы сейчас способны заручиться поддержкой большинства избирателей, но они уязвимы, пока против их лидера идет расследование.
Успех партии построен исключительно на авторитете Курца — центральной и незаменимой фигуры. То есть для успешного выступления на выборах партии сначала потребуется минимизировать любые угрозы имиджу Курца. А для этого ему надо опровергнуть подозрения в коррупции, чтобы не обременять себя в будущем очередными порциями резонансных спекуляций. Именно поэтому единственным вариантом для Курца осталось сохранение действующей коалиции с «Зелеными» путем перехода с поста канцлера на работу в парламент в руководство партийной фракцией. Ведь даже в случае перевыборов другие политические силы Австрии в настоящее время исключают возможность сотрудничества с партией Курца в будущем.
Теневой канцлер Курц
Рокировка с уходом Курца в парламент и приход на пост канцлера министра иностранных дел Александера Шалленберга представляется для действующего правительства наилучшим компромиссным решением. Дипломат Шалленберг устраивает «Зеленых», его кандидатура в качестве канцлера в итоге позволила продолжить их совместную работу в правительстве с партией Курца.
На эту тему
Шалленберг как член АНП будет де-факто следовать политической линии, которую определяет ее председатель. Тактически Курц сделал единственно верный шаг: без прямого присутствия в правительстве он сможет диктовать решения и повестку новому шефу кабмина, а значит, быть теневым канцлером Австрии, опирающимся на безоговорочную поддержку однопартийцев.
Курц — молодой, но опытный политик, который предпочитает контролировать каждый шаг своего окружения. Он дважды становился канцлером Австрии. Впервые пришел во власть в 2017 году, но в 2019-м был вынужден уйти в отставку из-за вотума недоверия парламента в результате внутриполитического скандала «Ибица-гейт» с участием экс-вице-канцлера Хайнца-Кристиана Штрахе. В 2019 году его партия снова победила на досрочных выборах, и он второй раз стал канцлером.
Рискнет ли 35-летний австриец и лидер ведущей политической партии Австрии в третий раз претендовать на пост канцлера, покажут время и результаты следствия. Сейчас же у него есть возможность посвятить себя личной жизни — в конце года ему предстоит стать отцом ребенка от спутницы жизни Сюзанны Тир.
Предвзятое следствие?
Тем временем в политической карьере Курцу потребуется запастись терпением в борьбе с обвинениями антикоррупционной прокуратуры. Этот следственный орган давно преследует его соратников из Австрийской народной партии. Эта прокуратура считается независимым ведомством, но интересным образом ее следователи уже оказывались вовлечены в предвзятые процессы.
Информационный фон вокруг дела Курца каждый раз также подогревает центральная австрийская пресса, в которую сначала просочился протокол постановления об обысках у его окружения, а затем массив данных личной СМС-переписки из изъятого в 2019 году мобильного телефона одного из фигурантов расследования, близкого к Курцу. Такие сведения порционно становятся достоянием общественности, хотя могут быть доступны только следствию. У стороннего наблюдателя возникает справедливый вопрос: кто и зачем передает прессе данные следствия?
Дальнейшая судьба Курца в государственной политике зависит от того, какие подробности из его личной переписки с фигурантами уголовного производства о коррупции могут всплыть в ходе расследования. Отсутствие информационных провокаций о других предполагаемых махинациях вполне может подготовить почву для досрочных парламентских выборов с участием Курца в качестве ведущего кандидата на пост канцлера. Его партии останется только дождаться выгодного момента, чтобы стать их триумфатором. Однако в 2021 году этого ожидать не стоит.
Передача массива функции C ++
Массив — это группа элементов одного типа данных. Многие функции выполняются над массивами либо в основной программе, либо вне ее, в функциях. В C ++ в случае функций нам нужно их передавать. Это делается с помощью параметров в качестве аргументов. Эти аргументы могут быть разными: массивы большого размера или массив указателей. В этом руководстве мы рассмотрим некоторые основные аспекты передачи массива с использованием различных параметров функций.
Синтаксис
[Тип возврата] [имя функции] (тип данных имя массива [размер массива])
{
тело функции
}
Пример 1
Рассмотрим пример, в котором нам нужно распечатать оценки студентов в программе C ++. Этот отпечаток будет взят в отдельной функции, а не в основной программе. Напротив, мы будем принимать входные данные в основной программе и передавать эти значения в функцию в качестве параметра. Рассмотрим функцию. В его параметре есть переменная типа данных массива, которая будет принимать значения массива.Здесь объявлен полный массив. Отметки будут отображаться с помощью цикла for. Как и в случае с массивами, нам нужны циклы для получения с них печати.
Переходя к функции main, мы объявляем массив с его размером и значениями. Поскольку мы должны вызвать функцию. Таким образом, метод состоит в том, что мы записываем имя функции с именем массива в параметре в качестве аргумента. Мы не определили размер массива.
Аргумент в параметре подразумевает адрес памяти массива.В параметре заголовка функции int m [7] преобразуется в int * m. Это включает тот же адрес, что и исходный массив. Когда мы используем m [5] в теле функции, мы собираемся манипулировать исходным массивом.
Отображение пустоты (int m [7])
В операционной системе Linux для получения вывода через терминал требуется установка некоторых предварительных условий. Ему нужен компилятор для компиляции и последующего выполнения кода в терминале командной строки. G ++ используется в C ++ для компиляции.
$ g ++ -o code3 code3.c
$ ./code3
Где –o используется для сохранения вывода из исходного файла в выходной файл.
Из вывода вы можете заметить, что все числа, инициированные в массиве в основной функции, передаются и отображаются через функцию отображения.
Пример 2
Другой пример передачи массива через параметр — передача многомерного массива функции. Здесь используется двумерный массив (2d).В основной функции нам нужно инициализировать массив.
Инициализация 2-мерного массива включает строку и столбец. И их порядок должен сохраняться на протяжении всей программы. 2-й массив инициализируется двумя числами в скобках. Как мы описали в инициализации 2 столбца.
Мы будем использовать только имя массива в параметре в качестве аргумента.
Теперь посмотрим, как работает функция отображения. При запуске функции требуется переменная массива, чтобы принять массив, переданный вызовом функции через основную программу.
Пустой дисплей (int n [] [2])
Обязательно указать количество столбцов. Для сравнения, в случае рядов это несущественно. Вот почему мы оставили здесь скобки строк пустыми, так как мы используем цикл for для отображения результатов. Но в случае двумерного массива мы используем вложенный цикл for. Он содержит два оператора for с двумя переменными в них.
Мы можем просмотреть вывод, используя тот же компилятор. Вы можете увидеть результаты, что каждое значение отображается отдельно со строкой и номером столбца.
Пример 3
Этот пример немного отличается от предыдущих. В этом примере мы упоминаем размер массива в параметре вызова функции. И в объявлении функции также вводится переменная, принимающая размер массива.
Начиная с основной программы, массив инициализируется значениями.
Avg = getAverage (баланс, 5);
Результат будет сохранен в переменной avg. Вместо того, чтобы передавать только имя массива, к параметру также добавляется размер массива.
Параметр также содержит переменную типа массива и целочисленный тип данных для получения размера массива. Тип основной программы — int, потому что она получит от функции целочисленное значение. В противном случае в остальных случаях он недействителен.
Теперь посмотрим на результат. Это значение видно через изображение, полученное из функции.
Пример 4
Этот пример касается определения максимального числа в массиве, фактически, из двух массивов.Здесь мы инициализируем два массива в основной программе. Оба массива отдельно передаются в функцию в отдельных вызовах функции
printMax (arr1);
printMax (arr2);
, где printMax — это имя функции, а arr — это массив. Результат не возвращается из функции и отображается там. Цикл For вычислит максимальное число в обоих массивах. Оператор if используется внутри цикла for. Заголовок функции:
void printMax (int arr [5])
Поскольку оба массива содержат разные значения, оба результата будут разными.
Пример 5
Этот пример представляет собой сводку всех типов массивов, передающих параметры. Это могут быть массивы размера, без размера или массивы указателей. Мы рассмотрим их по очереди.
В основной программе каждая функция объявляется первой. Вы можете указать разницу в их декларации.
Int sum1 (int tmp [5]);
Int sum2 (int tmp []);
Int sum3 (int * tmp);
Эти три массива показывают, что массивы могут передаваться с этими параметрами в функцию.
После инициализации функции у нас есть основная программа, в которой объявлен массив. В отличие от предыдущего примера, инициализируется один массив вместо двух, но он передается тремя разными способами. Теперь мы увидим выполненные здесь вызовы функций.
Итого = сумма1 (продажи);
Итого = сумма2 (продажи);
Итого = сумма3 (продажи);
Вывод отображается в основной функции, поэтому объявляется переменная, принимающая значение, возвращаемое функцией. Из всех трех вызовов функций видно, что здесь параметры одинаковые.Каждый массив содержит только имя массива. Но параметры функции, принимающей массив, другие.
Внутреннее тело всех трех функций одинаково, поскольку сумма всех чисел вычисляется с использованием цикла For. Методология и значения массива совпадают; только есть различие между параметрами функций. Следовательно, доказано, что мы можем использовать разные методы для приема массива или выполнять те же функции, и ответ один и тот же.Мы можем подтвердить это, проверив вывод. Используя ту же процедуру компиляции, мы получим результат, показанный на изображении ниже.
Как видите, ответ одинаков для всех трех используемых функций.
Заключение
В этой статье пользователь узнает о методе передачи массива в параметрах. Массивы можно обрабатывать во многих случаях, когда дело доходит до возврата значения или передачи его в аргументах.
MoonBooks: массивные открытые онлайн-блокноты
Как найти количество вхождений в списке кортежей в Python?
Дайдалос
/
CC BY-SA 4.0
/
10 октября 2021 г.
Как получить знак числа (например, -1 или +1) в Python?
Дайдалос
/
CC BY-SA 4.0
/
08 октября 2021 г.
Комментарий Supprimer un caractère d’une chaîne de caractères en python?
Bazinga
/
CC BY-SA 4.0
/
06 октября 2021 г.
Comment créer une matrice de nombres aléatoires avec numpy en python?
Bazinga
/
CC BY-SA 4.0
/
04 октября 2021 г.
Заменить комментарий или заменить его на питоне?
Bazinga
/
CC BY-SA 4.0
/
04 октября 2021 г.
Комментарий vérifier si un caractère est une lettre, un chiffre, un caractère spécial or un espace en python?
Bazinga
/
CC BY-SA 4.0
/
04 октября 2021 г.
Все заметки
Как создать список чисел на Python?
Дайдалос
/
CC BY-SA 4.0
/
09 марта 2018
Как преобразовать массив с плавающей запятой в целочисленный массив в Python?
Дайдалос
/
CC BY-SA 4.0
/
22 марта 2019
Комментарий Supprimer Element d’une Liste Avec Python?
Дайдалос
/
CC BY-SA 4.0
/
21 авг.2014 г.
Как создать диаграмму рассеяния с несколькими цветами в matplotlib?
Дайдалос
/
CC BY-SA 4.0
/
05 апреля 2019
Комментарий arrondir un nombre décimal en python?
Дайдалос
/
CC BY-SA 4.0
/
03 июн 2014
Как преобразовать изображение в оттенки серого с помощью Python?
Дайдалос
/
CC BY-SA 4.0
/
19 феврье 2019
Как найти наибольшее значение в списке и его индекс с помощью Python?
Дайдалос
/
CC BY-SA 4.0
/
27 марта 2019
Передающие массивы
Передающие массивы
2-4 ПЕРЕДАЧА МАССИВОВ В ПОДПРОГРАММЫ - МАССИВЫ НАСТРОЙКИ И ПРИНЯТИЯ РАЗМЕРА ************************************************* ********************* (Спасибо Крейгу Берли за важные исправления и вклад к этой главе) Массивы "внутренности" ------------------ Массив - это выделенная область в памяти вместе с информацией нужно было интерпретировать это правильно.Информация, необходимая для этого состоит из: 1) Тип данных элементов. Все элементы имеют один и тот же тип данных, поэтому естественно указать тот же тип данных для самого массива. В других слов есть один тип данных на массив, и он применяется ко всем элементам. 2) Количество размеров 3) Начальный и конечный индекс каждого измерения. 4) Указание порядка элементов в памяти Вся эта информация нужна компилятору для генерации ссылок. для элементов массива или реализовать операции с целым массивом.Поскольку Фортран компилятор компилирует каждую процедуру отдельно, эта информация должна быть доступна в вызываемой процедуре при передаче массива в процедуру. Возможные механизмы передачи информации о конфигурации массива представляют собой комбинации из следующих: 1) Явные объявления в вызываемой процедуре 2) Использование аргументов процедуры или общих блочных переменных 3) Игнорирование некоторой информации, если возможно 4) Специальная структура данных, передаваемая вместе с самим массивом В Fortran 90 при использовании массивов предполагаемой формы часть этой информации передается явно с помощью специальной структуры данных, называемой «вектор допинга» или «дескриптор».Во всех остальных случаях компилятор использует информацию выводится из объявлений данных вызываемой процедуры. Внутренняя структура массивов навязывается компилятором последовательно. интерпретируя область хранения как последовательность определенных элементов. Интерпретация выполняется кодом, который компилятор вставляет в программу, код реализует формулу, которая переводит индексы массива в память адреса. Например, формула для одномерного массива может быть похожий на: Адрес памяти = Базовый адрес + размер элемента * (индекс массива - начальный индекс) Начальный адрес по умолчанию в FORTRAN, конечно же, равен 1.См. Раздел о порядке хранения массива для описания FORTRAN. порядок хранения "основного столбца" и его влияние на обработку массива циклы и управление памятью. Размеры массива FORTRAN 77 определяются во время компиляции, 'внешнее' объявление массива выделяет кусок памяти, а размер этого фрагмента памяти нельзя изменить во время выполнения. Передача массивов в подпрограммы ----------------------------- Массивы, объявленные во «внешней» процедуре (вызывающей процедуре или некоторая процедура, которая вызвала его) может быть передана другой процедуре (вызываемая процедура).Обратите внимание, что информация о размерах и типах данных обычно не передается с переменными (например, и массивами). Как ФОРТРАН компилируется каждую процедуру отдельно, можно интерпретировать одну и ту же область хранения по-разному в каждой процедуре без предупреждения. Большинство компиляторов FORTRAN передают массивы, передавая адрес массив, в этом случае все подпрограммы, использующие массив, будут работать над той же (и единственной) копией. Стандарт FORTRAN позволяет передавать массив другим методом, называемым копирование в / из или копирование / восстановление.Этот метод не популярен на однопроцессорные машины, копирующие массив при каждом вызове процедуры, заставит большие массивы снова и снова дублироваться в памяти, копирование в / из только базового адреса массива выполняется многими FORTRAN реализации. На машинах с распределенной памятью копирование in / out происходит быстрее, больше эффективно перемещать массив по сети одним куском. Этот способ также использовался в некоторых ранних стековых машинах, например в некоторых Серия мэйнфреймов. Если ваш компилятор использует копирование в / из, некоторые нестандартные приемы будут не работает, эл.грамм. объявление массивов длиной 1 и большего размера индексы массива (которые обязательно выходят за границы). Когда массив объявляется в самой внешней процедуре, компилятор выделяет для него память. Когда вы передаете массив с помощью CALL оператор, компилятор фактически передает базовый адрес того же массив в вызываемую процедуру. Когда вызываемая процедура работает на массив, в котором он работает в том же массиве - использует то же хранилище памяти области, массив не «копируется» в другую область памяти (но может быть в некоторых случаях в некоторых системах Fortran).Короче говоря, память, используемая в массиве, выделяется в «самом верхнем» объявление и повторно используется при передаче массива другим процедурам. Сравнение различных типов массивов (и строк) -------------------------------------------------- Более подробное объяснение см. Ниже. | Синтаксис объявления | Физический размер в | Логический размер в | | называется рутиной | называется рутиной ------------------ | -------------------- | ---------- --------- | ----------------- Постоянный | ЦЕЛОЕ ARR (10) | Постоянно во всем | То же, что и (создано / прошло) | | призывы | физический размер ------------------ | -------------------- | ---------- --------- | ----------------- Регулируемый | ЦЕЛОЕ ARR (N) | Размер у него был | Какое бы значение N (прошло) | Фиктивные аргументы N & ARR | в звонилке | имел при входе ------------------ | -------------------- | ---------- --------- | ----------------- Предполагаемый размер | ЦЕЛОЕ ARR (*) | Размер у него был | Компилятор (прошло) | | в звонилке | не знает этого ------------------ | -------------------- | ---------- --------- | ----------------- Автоматическая ~ | ЦЕЛОЕ ARR (N) | Какое бы значение N | То же, что и (создано) | N фиктивный аргумент | имел при входе | физический размер ------------------ | -------------------- | ---------- --------- | ----------------- Предполагаемая форма ~~ | ЦЕЛОЕ ARR (:) | Те же границы и размер | То же, что и (прошло) | ARR фиктивный аргумент | как в звонилке | физический размер ------------------ | -------------------- | ---------- --------- | ----------------- ~ Автоматические массивы поддерживаются в g77 и Fortran 90 ~~ Массивы предполагаемой формы поддерживаются в Fortran 90 ------------------ | -------------------- | ---------- --------- | ----------------- Постоянная строка | ПЕРСОНАЖ ST * 10 | константа во всех | так же, как (создано) | | призывы | физический размер ------------------ | -------------------- | ---------- --------- | ----------------- Пройденная длина | ПЕРСОНАЖ ST * (*) | Независимо от размера | так же, как строка (передана) | | имел в звонилке | физический размер ------------------ | -------------------- | ---------- --------- | ----------------- Проблема повторного объявления --------------------- Когда вы передаете массив в подпрограмму, вы действительно (в большинстве компиляторов) передать адрес памяти начала массива.В начале вызываемой подпрограммы компилятор должен иметь также информация о размерах. Информация о размерах (с порядком элементов памяти) достаточно, чтобы компилятор сгенерировал код для вызываемого подпрограмма, ничего не зная о вызывающей подпрограмме. Оператор параметра - это «правильный» способ явно объявить размер массива: ЦЕЛОЕ * MAXDATA C ------------------------------------------------- ----------------- ПАРАМЕТР ( * MAXDATA = 1000) C ------------------------------------------------- ----------------- НАСТОЯЩИЙ * ДАННЫЕ (МАКС.ДАННЫЕ) Явное переопределение размера массива в вызываемой подпрограмме не очень хорошая практика программирования: 1) Чтобы изменить размер массива, вам нужно охотиться для него в каждой подпрограмме, которая его использует.2) Такая подпрограмма не может быть повторно использована в другой программе. без изменения значения параметра, и поэтому не может быть эффективно используется в библиотеке подпрограмм. 3) Повторное использование подпрограммы в той же программе может привести к до абсурда, несколько экземпляров одного и того же подпрограмма с разными значениями параметров будет должны быть сохранены. Мы видим, что явные повторные декларации несовместимы с хорошими практика программирования. Нам нужен способ передать размерную информацию подпрограмме, тем самым сделав ее более гибкой, или откажитесь от некоторых контроль размеров компилятора.Итак, что нам нужно сделать, это передать базовый адрес массива и некоторые дополнительные переменные, содержащие размерную информацию для подпрограммы, и скажите компилятору использовать все это при доступе к массиву. В FORTRAN вы говорите компилятору выполнить этот трюк, используя регулируемого размера или откажитесь от некоторого контроля размеров с помощью синтаксис предполагаемого размера. Массивы регулируемого / предполагаемого размера ------------------------------- Метод регулируемого размера позволяет не только пройти «правильный» информация о размерах, но также и для "перенастройки" массива - скажите компилятор обрабатывает область хранения исходного массива, как если бы он принадлежал к массиву с разными размерами.В методе предполагаемого размера вы передаете исходный массив, отказываясь от контроль размеров компилятором. Сделать это можно только с размером одной «границы», а именно последней верхней. Два специальных метода передачи массивов очень полезны, когда вы создавать процедуры общего назначения. Их также можно комбинировать вместе, вы можете передать «последнее» измерение с синтаксисом предполагаемого размера и другие измерения с синтаксисом регулируемого размера. В стандарте C такого механизма нет (в некоторых компиляторах он реализовано, e.грамм. параметризованные массивы gcc), и вам придется прибегнуть к до странно выглядящих уловок (см. приложение о указателях и массивах C). Пример массивов регулируемого и предполагаемого размера --------------------------------------------- В следующем примере мы передаем ОБА массив и размерный информация в подпрограмму двумя способами: 1) Передача массива и размерной информации в списке аргументов. Это обычный РЕГУЛИРУЕМЫЙ МЕТОД РАЗМЕРА МАССИВА. 2) Передача массива в списке аргументов как ПРИНЯТЫЙ РАЗМЕР МАССИВА.Информация о размерах за исключением того, что верхняя граница последнего измерения либо неявно (нижняя граница = 1), передается с метод настраиваемого массива или является постоянным. C ================================================= ================= C Основная программа для обоих примеров C ================================================= ================= ПРОГРАММА ТЕСТ1 INTEGER N ПАРАМЕТР (N = 10) НАСТОЯЩИЙ Y (N) C ------------------------------------------------- ----------------- Y (1) = 0.123456 ВЫЗВАТЬ ЛЮБОЙ) ЗВОНИТЕ B (Y) C ------------------------------------------------- ----------------- КОНЕЦ C ================================================= ================= C Метод массива регулируемого размера C ================================================= ================= ПОДПРОГРАММА A (N, Y) INTEGER N НАСТОЯЩИЙ Y (N) C ------------------------------------------------- ----------------- ЗАПИСЫВАТЬ (*,*) WRITE (*, *) 'Регулируемый массив:', Y (1) C ------------------------------------------------- ----------------- ВОЗВРАЩЕНИЕ КОНЕЦ C ================================================= ================= C Метод предполагаемого размера C ================================================= ================= ПОДПРОТИНКА B (Y) НАСТОЯЩЕЕ Y (*) C ------------------------------------------------- ----------------- ЗАПИСЫВАТЬ (*,*) WRITE (*, *) 'Массив предполагаемого размера:', Y (1) C ------------------------------------------------- ----------------- ВОЗВРАЩЕНИЕ КОНЕЦ Обе подпрограммы запишут первый элемент массива Y.Кстати, вы не можете написать весь массив предполагаемого размера, используя только имя массива, но вы можете сделать это с помощью настраиваемых массивов и, конечно, с массивами, размеры которых объявлены с константами. Внутреннее устройство метода предполагаемого размера ------------------------------------ Чтобы понять, что на самом деле происходит в методе предполагаемого размера, давайте посмотрим на формулу перевода индексов массива в память адреса. Для упрощения алгебры возьмем случай двумерного массива с индексами, начинающимися с 1 (по умолчанию).Больше размеров и прочее индексы усложняют формулу, но не меняют результат. ЦЕЛОЕ i, j НАСТОЯЩИЙ массив (M, N) Учитывая ссылку на Array (i, j), адрес в памяти этого Элемент вычисляется из базового адреса массива следующим образом: Адрес памяти = Базовый адрес + Размер элемента * (i - 1) + Размер элемента * (j - 1) * M Поскольку FORTRAN использует схему хранения массивов по основным столбцам, наша формула не включает N - размер последнего измерения! Аналогичные результаты получены и в общем случае - ВЕРХНЯЯ ОЦЕНКА ПОСЛЕДНЕГО РАЗМЕРА не требуется для расчета смещения конкретный элемент массива.Итак, верхнюю границу можно оставить не указано (обозначено в коде знаком «*»). Верхняя граница последнего измерения нужна только для определения максимально допустимое значение последнего индекса, и, следовательно, размер всего массива. Массив с неуказанной конечной верхней границей является «предполагаемым массивом», независимо от того, регулируется ли он (верхний или нижний граница любого измерения является непостоянным выражением) или константой. Кстати, максимально допустимое количество измерений в FORTRAN 77 7, несколько произвольный предел, вероятно, наложенный, чтобы удовлетворить количество индексных регистров в старом мэйнфрейме IBM.Проблемы с массивами предполагаемого размера ------------------------------- Из приведенного выше обсуждения следует, что компилятор не должны знать размер последнего измерения, чтобы вычислить память адреса из индексов массива, поэтому он может обойтись без него, если мы не попросите его сделать что-то, что требует этой информации, например выполнить Операция ввода-вывода сразу для всего массива, что требует знания размер массива. Ответственность за соблюдение границ последнего измерения массива предполагаемого размера находится на программаторе, например.грамм. проверка границ опция компилятора не поможет вам в этом случае и проверьте выход за пределы ссылки для вас. Массивы предполагаемого размера также могут быть проблемой для специализированного Fortran. реализации для обработки, возможно, даже невозможно. Например, компилятор для конфигурации с двумя машинами, где граница между машины - это обычно процедура, а аргументы между процедурами поэтому копируются как часть вызова, поэтому должны знать, сколько информация для копирования для каждого аргумента, но не может надежно определить это для массива предполагаемого размера.Некий компилятор для двухпроцессорной машины, использующий такой подход просто пропустил любую такую процедуру, распечатал диагностику, а это означало любая процедура с массивом предполагаемого размера не может быть вызвана кодом тот "жил" на "другом" процессоре. Массивы предполагаемого размера и символьные строки ----------------------------------------- Передача символьной переменной (строки) в процедуру с помощью символа '* (*)' синтаксис на первый взгляд может показаться использованием метода предполагаемого размера, но это не так, потому что в этом случае весь код, вызывающий процедуру компилируется для передачи фактической длины любой строки предполагаемой длины, поэтому длина известна процедуре во время выполнения.ПРОГРАММА ТЕСТ CHARACTER строка * 80 ...................................... CALL SUB1 (строка) ...................................... КОНЕЦ SUBROUTINE SUB1 (строка) ХАРАКТЕР строка * (*) ............................ ВОЗВРАЩЕНИЕ КОНЕЦ В этом примере 'строка' НЕ передается методом предполагаемого размера, и ограничение ввода-вывода для массивов предполагаемого размера к нему не применяется. Вы _ можете_ объявить фиктивную переменную CHARACTER, используя CHARACTER * (*) синтаксис, а затем использовать его при вводе-выводе - потому что длина передается вызывающий абонент во время выполнения.Вы не можете использовать предполагаемый _array_ в вводе-выводе, поэтому вы не можете, например, выполнить «WRITE (10) CHA» с учетом «CHARACTER * 1 CHA (*)», хотя некоторым люди, это выглядит так же, как если бы был указан "CHARACTER * (*) CHA", в этом случае ЗАПИСЬ будет действительной. Внутренние механизмы для передачи длины струн -------------------------------------------------- --- Есть 4 метода (так говорят): 1) Дополнительная переменная, скрытая от программиста после конца списка аргументов.Это метод, используемый большинством компиляторов UNIX f77. 2) Использование дескриптора - специальной структуры данных, которая содержит размер строки, адрес, который она начинается, и, может быть, какая-нибудь «опознавательная подпись». Например, дескриптор фиксированной длины, используемый DEC FORTRAN на VMS. является одним из большого семейства подобных дескрипторов, он имеет следующие структура (каждая «ячейка» имеет длину байта): + ------ + ------ + + ------ + + ------ + + ------ + ------ + ---- - + ------ + | | | | 14 | | 1 | | | | | | + ------ + ------ + + ------ + + ------ + + ------ + ------ + ---- - + ------ + Длина данных Опис.Адрес первого байта строка в хранилище данных класса типа (строка) байтовый код код (без знака) ---?> Высшие адреса При передаче строки адрес первого байта (слева) дескриптор передается, и вызываемая процедура может получить доступ к своим полям.
Вернуться на страницу содержания
массивов VBA — передача массивов в
передача массивов в
Можно передать массив в подпрограмму или функцию.
Массивы всегда передаются по ссылке (ByRef).
Это означает, что любые изменения в массиве будут переданы обратно вызывающей программе.
Вы можете передавать как динамические, так и фиксированные массивы подпрограммам и функциям.
Dim myarray () As String 'динамический массив
Dim myarray (от 1 до 3) Фиксированный массив As String
Call MyMethod (myarray)
Dynamic Arrays
Если вы запустите подпрограмму DynamicArray1, вы увидите, что значения в myDynamicArray фактически изменены.
Public Sub DynamicArray1 ()
Dim icount As Integer
Dim myDynamicArray () As LongReDim myDynamicArray (от 1 до 10)
Для icount = LBound (myDynamicArray) в UBound (myDynamicArray) icount = icount (myDynamicArray)
myDynamicArray
myDynamicArrayВызов DynamicArray2 (myDynamicArray)
For icount = LBound (myDynamicArray) to UBound (myDynamicArray)
Debug.Print myDynamicArray (icount)
Next icount
EndIn DubArrayPublic Sub icount как целое число
Для icount = LBound (myInternalArray) to UBound (myInternalArray)
myInternalArray (icount) = myInternalArray (icount) * 2
Next icount
End Sub
Параметр myInternalArrayRef должен быть объявлен с параметром ByInternalArray.По умолчанию используется
ByRef, поэтому его можно опустить, но рекомендуется включить его.
Вы получите ошибку компиляции, если параметр myInternalArray объявлен с помощью ByVal.
Тип данных массивов должен быть одинаковым. В этом случае мы используем тип данных Long.
Вы получите ошибку компиляции, если типы данных различны.
Фиксированные массивы
Они также известны как статические массивы.
Фиксированные массивы также могут передаваться в подпрограммы и функции.
Public Sub FixedArray1 ()
Dim myFixedArray (1 to 5) As Long
Call FixedArray2 (myStaticArray)
End SubPublic Sub FixedArray2 (ByRef myInternalArray () As Long) 019 End Sub
передаваться с использованием ByRef.
End Sub
Объявление параметра myInternalArray одинаково независимо от того, передаете ли вы динамический массив или фиксированный массив.
По какой-то странной причине при передаче в фиксированных массивах числовые типы данных не должны совпадать ??
Любой тип данных
Можно передать массив любого типа данных в подпрограмму или функцию.
Этого можно достичь, объявив параметр как вариант . [Не массив вариантов, то есть Variant ()]
Создание подпрограммы (или функции), которая принимает один параметр Variant, позволит вам передавать массивы любого типа данных.
Это помещает весь массив в одну переменную Variant с именем myInternalArray.
Для проверки аргумента можно использовать функцию ISARRAY .Public Sub AnyDataType1 ()
Dim myIntegerArray () As Integer
Dim myLongArray () As Long
Dim myDoubleArray () As Double
Dim myStringArray () As StringCall AnyDataTyperay Call
AnyDataTyperay Call
MyIntegerArray (myDoubleArray)
Call AnyDataType2 (myStringArray)
End SubPublic Sub AnyDataType2 (ByRef myInternalArray As Variant)
If (VBA.IsArray (myInternalArray) = True) Then
End If
End Sub
Преимущество объявления массива как варианта означает, что его можно легко передать в процедуры и вернуть из функций.
Когда вы объявляете свои массивы как варианты, вы можете стереть массив, просто присвоив ему значение Empty.
Чтобы проверить, инициализирована ли переменная варианта (массива), то есть равна ли она «Ничего», используйте «Если vArray IS Nothing Then»
Не забудьте всегда инициализировать массив вариантов пустым.Также возможно создать массив и заполнить его массивами (массив массивов).Важно
Вы не можете передать тип данных Variant подпрограмме, которая ожидает явно типизированный массив.
Вы не можете передать массив в качестве необязательного параметра. Однако это можно сделать, если вы объявите параметр как Variant.
Объявление вашего параметра как Variant () не позволяет передавать массив данных любого типа.© 2021 Better Solutions Limited. Все права защищены.© 2021 Better Solutions Limited TopPrevNext
Передача и возврат массивов с функциями
В VBA вы можете передавать массивы в процедуры (Subs,
Функции и свойства) и функции
и Properties (только Property Get) могут возвращать массивы в качестве своего результата. (Примечание
что возвращающий массив как результат функции или свойства был добавлен в
Office 2000 - функции в Office 97 не могут возвращать массивы.) Однако вы должны знать о
ограничения на передачу массивов.Эта страница предполагает, что вы знакомы с
основы массивов VBA и разница между
статический
и
динамичный
множество.В качестве общей практики кодирования я всегда использую динамические массивы и использую ReDim для определения размера массива
необходимые габариты. Это делает код более
гибкий и многоразовый. Довольно редко я буду иметь дело с фиксированным
количество сущностей или объектов, количество которых известно во время разработки. С использованием
динамические массивы позволяют программному обеспечению подбираться под конкретную задачу.В
На самом деле, я не могу представить себе ситуацию, в которой статический массив был бы лучше
в динамический массив.Процедуры и код на этой странице используют
функции поддержки массива, описанные в разделе Функции
Для страницы массивов VBA. Если вы собираетесь использовать пример кода на
эту страницу в коде VBA, вы должны скопировать функции на этой странице в
модуль в вашем проекте VBA или получите
модуль кода здесь и импортируйте это
модуль в ваш проект VBA.Мы будем использовать ту же терминологию, что и на
страницу Функции для массивов VBA.Передача массивов процедурам
Процедура (подпрограмма, функция или свойство) может принимать массив в качестве входного параметра.
Первое, что нужно понять, это то, что массивы всегда передаются
ссылка (ByRef).
Вы получите ошибку компилятора, если попытаетесь передать массив
ByVal.
(См. Интерактивную справку VBA по теме Подписка для получения информации о
ByRef и ByVal.) Это означает, что любая модификация, которую вызываемая процедура делает с массивом
параметр выполняется на фактическом массиве, объявленном в вызывающей процедуре. Это
показано в следующем коде:Sub AAATest () Dim StaticArray (от 1 до 3) до длины Dim N As Long StaticArray (1) = 1 StaticArray (2) = 2 StaticArray (3) = 3 PopulatePassedArray Arr: = StaticArray Для N = LBound (StaticArray) To UBound (StaticArray) Debug.Print StaticArray (N) Следующий N Конец подписки Sub PopulatePassedArray (ByRef Arr () до конца) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'PopulatePassedArray 'Это помещает некоторые значения в обр.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim N As Long Для N = LBound (Arr) To UBound (Arr) Arr (N) = N * 10 Следующий N Конечный переводникВ этом коде массив
StaticArray
передается в
Процедура заполненияPassedArray. В
ByRef
ключевое слово не требуется в списке параметров процедуры
PopulatePassedArray
(ByRef
по умолчанию в VB / VBA), но я обычно включаю
ByRef в
объявления параметров, если я собираюсь изменить эту переменную.Он служит
напоминание, что переменная в вызывающей процедуре будет
изменен вызываемой процедурой. Я не включаю
ByRef
ключевое слово для переменных, содержимое которых я не собираюсь изменять. Вы можете смело опускатьByRef, если
Вы предпочитаете. Поскольку массив
StaticArray передается по ссылке, переменная
StaticArray
в вызывающей процедуре
AAATest модифицируется кодом в вызываемом
процедура
PopulatePassedArray.Проще говоря,
коммерческого качества, вы должны сначала протестировать, чтобы убедиться, что
массив Arr
был фактически выделен
а массив одномерный. Вы можете использовать
IsArrayAllocated
а также
NumberOfArrayDimensions
функции, описанные в разделе "Функции для массивов VBA"
страницу, чтобы проверить эти условия. Например, вы могли бы написать вызываемую процедуру
как:Sub PopulatePassedArray (ByRef Arr () до длины) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'PopulatePassedArray 'Это помещает некоторые значения в обр.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim N As Long Если IsArrayAllocated (Arr: = Arr) = True, то Если NumberOfArrayDimensions (Arr: = Arr) = 1, то Для N = LBound (Arr) To UBound (Arr) Arr (N) = N * 10 Следующий N Еще Debug.Print «Массив имеет несколько измерений». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Примите все необходимые меры 'для многомерного массива, 'например, изменение размера массива. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Еще Отлаживать.Выведите «Массив не выделен». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Выполните все необходимые действия с 'нераспределенный массив, например ReDim 'массив. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Конечный переводникВы могли заметить, что статический массив
StaticArray
в AAATest
имеет тот же тип данных (Long)
как массив Arr
объявлен в списке параметров для
PopulatePassedArray
. Это не случайно.Правило здесь состоит в том, что тип данных
массив, объявленный в вызывающей процедуре , должен соответствовать типу данных
объявлен в списке параметров вызываемой процедуры.
Хотя вы можете объявить простой параметр
Как вариант
чтобы принять параметр любого типа данных, не работает
для массивов. Это очень распространенное заблуждение, что объявление
параметр функции
Как вариант ()
позволит вам принять массив любого типа.Это совершенно неверно. Вы не можете объявить
массив в списке параметров вызываемой процедуры
Как вариант ()
принимать любой массив типов данных. Типы данных должны явно совпадать;
в противном случае вы получите сообщение « Несоответствие типов: массив или пользовательский тип.
ожидал. "ошибка при компиляции и запуске кода. Если вы объявите
параметр функции
Как вариант ()
тогда вы должны передать массив вариантов.Более того, если параметр функции объявлен как
массив, вы не можете передать один вариант в качестве параметра функции, даже если
Вариант содержит массив нужного типа данных.Например,
следующий код будет компилироваться , а не .Sub AAATest () Dim V как вариант Dim L (от 1 до 3) по длине L (1) = 100 L (2) = 200 L (3) = 300 V = L BBB L '<<< Работает, потому что L - длинный массив. BBB V '<<< Ошибка компилятора здесь. Сам V не является массивом, как ожидает BBB. Конец подписки Sub BBB (Arr () до конца) Отладка.Печать Arr (LBound (Arr)) Конечный переводникТак как массив передан от вызывающей процедуры к вызываемой процедуре
передается по ссылке, вызываемая процедура может использовать
ReDim
оператор для изменения размера переданного массива и / или количества измерений
(переданный массив должен быть объявлен как динамический массив в вызывающей процедуре,
но его не нужно выделять).Это прекрасно
законно и действительно весьма полезно. Например, в описанных ниже процедурах
массив DynArray
объявлен как динамический массив в
AAATest,
и его размер изменяется столько раз, сколько необходимо, чтобы сохранить результаты в
PopulateArrayWithCellValuesGreaterThan10
процедура.Sub AAATest () Dim DynArray () As Double 'Обратите внимание, что этот массив не имеет размера 'в заявлении Dim. Мы будем использовать ReDim 'в вызываемой процедуре для изменения размера.Dim N As Long '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Вызов PopulateArrayWithCellValuesGreaterThan10 для изменения размера 'массив и заполните его элементы значениями. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' PopulateArrayWithCellValuesGreaterThan10 Arr: = DynArray, TestRng: = Range ("A1: A10") '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Убедитесь, что PopulateArrayWithCellValuesGreaterThan10 'выделил массив.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Если IsArrayAllocated (Arr: = DynArray) = True, то Для N = LBound (DynArray) To UBound (DynArray) Отладка. Печать DynArray (N) Следующий N Конец, если Конец подписки Sub PopulateArrayWithCellValuesGreaterThan10 (ByRef Arr () как Double, TestRng как диапазон) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'PopulateArrayWithCellValuesGreaterThan10 ' 'Это изменяет размер Arr и помещает в него значения 'в диапазоне TestRng, превышающем 10.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Dim Rng As Range Dim Ndx As Long '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' «Убедитесь, что TestRng - это не« Ничто ». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Если TestRng - ничто, тогда MsgBox "TestRng Is Nothing" Выйти из подводной лодки Конец, если '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Прокрутите диапазон. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Для каждого звонка в TestRng.Cells Если IsNumeric (Rng.Value) = True, то Если Rng.Значение> 10 Тогда Ndx = Ndx + 1 ReDim Preserve Arr (от 1 до Ndx) Arr (Ndx) = CDbl (Rng.Value) Конец, если Конец, если Следующий Rng Конечный переводникВ
PopulateArrayWithCellValuesGreaterThan10
процедура, массив Arr
(это тот же массив, что и
DynArray в
AAATest)
изменяется с помощью ReDim
Сохранять оператор каждый раз, когда значение ячейки больше
чем 10
столкнулся. Хотя это совершенно законный код, и он иллюстрирует изменение размера
параметр массива, код не является ни безопасным, ни эффективным.Код
не проверяет, является ли массив динамическим и, следовательно, его размер может быть изменен. Если
нам передали статический массив,
мы получили бы ошибку времени выполнения 10 (" Массив фиксированный или временно
заблокирован . ") при вызове ReDim
Сохранять. Более того, код вызывает ReDim
Сохранять заявление любое количество раз, столько раз
раз, если значение ячейки превышает 10. ReDim
Консервирование - дорогостоящая операция (особенно
с большими массивами строк или вариантов) и должен быть
используется экономно.
Ниже показана гораздо лучшая версия процедуры.Sub AAATest () Dim DynArray () As Double 'Обратите внимание, что этот массив не имеет размера 'в заявлении Dim. Мы будем использовать ReDim 'чтобы изменить размер позже. Dim N As Long PopulateArrayWithCellValuesGreaterThan10 Arr: = DynArray, TestRng: = Range ("A1: A10") Если IsArrayAllocated (Arr: = DynArray) = True, то Для N = LBound (DynArray) To UBound (DynArray) Отладка. Печать DynArray (N) Следующий N Конец, если Конец подписки Sub PopulateArrayWithCellValuesGreaterThan10 (ByRef Arr () как Double, TestRng как диапазон) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'PopulateArrayWithCellValuesGreaterThan10 ' 'Это изменяет размер Arr один раз до максимального числа 'элементов, которые мы можем использовать, заполняет массив 'элементы, а затем использует ReDim Preserve для 'изменить размер массива на количество элементов 'действительно используется.Это позволяет избежать вызова Redim 'Сохранить для каждой ячейки в диапазоне. ' 'Он вызывает IsArrayDynamic, чтобы гарантировать, что Arr '- это динамический массив, размер которого можно изменять. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Dim Rng As Range Dim Ndx As Long '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' «Убедитесь, что TestRng - это не« Ничто ». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если TestRng - ничто, тогда MsgBox "TestRng Is Nothing" Выйти из подводной лодки Конец, если '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Вызов IsArrayDynamic, чтобы убедиться, что 'что у нас есть динамический массив.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если IsArrayDynamic (Arr: = Arr) = True, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'ReDim Arr к количеству ячеек 'в TestRng. Это максимум 'возможные записи, которые мы могли бы использовать - 'количество ячеек в TestRng ' диапазон. Мы не используем Preserve 'с ReDim здесь, потому что мы не хотим 'для сохранения существующих ценностей. 'Любые значения в данный момент в массиве 'будет потеряно. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' ReDim Arr (1 To TestRng.Cells.Count) Ndx = 0 Для каждого звонка в TestRng.Cells Если IsNumeric (Rng.Value) = True, то Если Rng.Value> 10 Тогда Ndx = Ndx + 1 Arr (Ndx) = CDbl (Rng.Value) Конец, если Конец, если Следующий Rng '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'ReDim Preserve, чтобы уменьшить размер 'массив только до такого количества элементов 'как мы использовали. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' ReDim Preserve Arr (от 1 до Ndx) Еще '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код для случая, если Arr не является динамическим.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Выйти из подводной лодки Конец, если Конечный переводникВ этом
код, сначала вызываем функцию
IsArrayDynamic
(эта функция проиллюстрирована в разделе "Функции для массивов VBA"
page), чтобы гарантировать, что Arr
это динамический массив, размер которого можно изменять. Если эта функция возвращает True,
массив является динамическим, и мы можем изменить его размер. Если функция возвращает False,
массив статичен, и мы, вероятно, вызовем ошибку или просто выйдем из подпрограммы.Затем процедура вызывает ReDim один раз, чтобы изменить размер массива до количества ячеек в
диапазон (максимально возможный размер, который нам понадобится для массива), а затем
вызывает ReDim Preserve
в конце, чтобы уменьшить размер до фактического количества фактически используемых элементов. (ReDim
Консерв обычно используется для увеличения
размер массива, но также можно использовать его для уменьшения размера
множество). Обратите внимание, что первый вызов ReDim
не использует заповедник
ключевое слово.Это потому, что мы не хотим сохранять какие-либо ценности, которые могут быть
в массиве. Вызов ReDim
без сохранения
изменяет размер массива, но уничтожает его существующее содержимое.Обратите внимание, что когда вы объявляете массив в вызываемой процедуре
список параметров, вы не (и не можете) включать его размер, даже если это
статический массив. Например,
следующий код недопустим и будет компилироваться , а не :Public Sub CalledProcedure
(Прибл. (От 1 до 3) по длине)Вместо этого вы используете такой код, как
Public Sub CalledProcedure (Arr () As Long)
Отсутствие нижней и верхней границ в круглых скобках
в объявлении параметра
Арр, однако,
не означает, что массив каким-то образом был сделан динамическим массивом.Если оно
был объявлен статическим в вызывающей функции, он остается статическим при доступе
вызываемая процедура. Символы "()" после имени параметра в вызываемом
список параметров процедуры просто указывает, что массив, статический или
динамический, передается. Вызываемая процедура определяет
является ли переданный массив статическим или динамическим, если необходимо. Вы можете
использоватьIsArrayDynamic
функция для проверки этого условия.Невозможно преобразовать статический массив в динамический.Если это
размер в тусклом
заявление, его размер никогда не может быть изменен. Его размер фиксирован, и любая попытка
изменение размера массива вызовет ошибку компилятора («Массив уже измерен» ) . Конечно, вы можете создать новый
динамический массив и загрузите в него содержимое статического массива:Dim StaticArray (от 1 до 3) As Long Dim DynArray () как двойной Dim Ndx As Long 'Загрузить StaticArray с некоторыми данными ReDim DynArray (LBound (StaticArray) в UBound (StaticArray)) Для Ndx = LBound (StaticArray) To UBound (StaticArray) DynArray (Ndx) = StaticArray (Ndx) Далее NdxВ этом случае типы данных могут не совпадать.Они просто
должны быть совместимы (например, оба должны быть числовыми типами).Вы можете передавать статические массивы процедурам так же, как и
динамические массивы. Как и в случае с динамическими
массивы, статические массивы передаются по ссылке. Единственная разница в том, что вы не можете
изменить размер статического массива. Например, следующий код передает статический массив
к функции.Sub AAATest () Dim StaticArray (от 1 до 3) до длины Тусклый результат до тех пор, пока не закончится StaticArray (1) = 10 StaticArray (2) = 20 StaticArray (3) = 30 Результат = SumArray (Arr: = StaticArray) Отлаживать.Результат печати Конец подписки Функция SumArray (Arr () As Long) As Long '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' SumArray 'Это суммирует элементы Arr и возвращает ' Общая. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Dim N As Long Dim Total As Long Для N = LBound (Arr) To UBound (Arr) Итого = Итого + Прибыль (N) Следующий N SumArray = Всего Конечная функцияФункция SumArray просто перебирает
массив, суммирующий значения, и возвращает результат.Поскольку тип данных массива в вызывающей процедуре должен соответствовать
тип данных в объявлении параметра массива в вызываемой процедуре, вы
может задаться вопросом, как вызвать процедуру, которая может обрабатывать различные другие данные
типы, которые
может быть неизвестно до времени выполнения. Например, как бы
SumArray
быть написанным для обработки массивов целых или двойных, а также длинных?Чтобы передать массив любого типа в
процедура, не объявляйте параметр как массив.Вместо этого объявите его как
Вариант (не массив вариантов). Одна переменная Variant может
содержат массив. Это показано в коде
ниже.Sub AAATest () Dim StaticArray (от 1 до 3) как двойной Тусклый результат как двойной StaticArray (1) = 10 StaticArray (2) = 20 StaticArray (3) = 30 Результат = SumArray (Arr: = StaticArray) Отладка.Результат печати Конец подписки Функция SumArray (Arr As Variant) As Double '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' SumArray 'Это суммирует элементы Arr и возвращает ' Общая.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Dim N As Long Dim Total As Double '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что Arr - это массив. '' '' '' '' '' '' '' '' '' '' '' ' Если IsArray (Arr) = True, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что массив выделен. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если IsArrayAllocated (Arr: = Arr) = True, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что Arr одномерный. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если NumberOfArrayDimensions (Arr: = Arr) = 1, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что Arr - это массив числового типа.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если IsNumericDataType (Arr) = True, то Для N = LBound (Arr) To UBound (Arr) '' '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что Arr (N) является числовым. '' '' '' '' '' '' '' '' '' '' '' '' ' Если IsNumeric (Arr (N)) = True, то Итого = Итого + Прибыль (N) Конец, если Следующий N Еще Debug.Print «Массив не является числовым». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Код в случае, если Arr не числовой.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Функция выхода Конец, если Еще Debug.Print «Массив не одномерный». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Код в случае, если Arr многомерный. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Функция выхода Конец, если Еще Debug.Print «Массив не выделен». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код на случай, если Arr не выделен. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Функция выхода Конец, если Еще Отлаживать.Печать «Ввод не массив». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код на случай, если Arr не является массивом. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Функция выхода Конец, если SumArray = Всего Конечная функцияВы заметите, что эта версия
SumArray
имеет гораздо больше ошибок, чем в более ранней версии. Это потому, что в
первая версия Arr была объявлена как массив Long. Это означает, что мы
не нужно было проверять, был ли это массив, и нам не нужно было проверять
были ли его элементы числовыми.Но в этой более поздней версии Arr - это
Вариант, который может содержать что угодно, поэтому нам нужна дополнительная проверка ошибок, чтобы гарантировать
все действительно.
С помощью этого кода вы можете перейти к массиву любого типа
в SumArray.ПРИМЕЧАНИЕ. Вы не можете передать массив в качестве необязательного параметра в процедуру. Если вам нужна такая функциональность, объявите параметр
В качестве варианта, а затем используйте функцию IsArray, чтобы проверить, действительно ли параметр является массивом.Использование ParamArray
Альтернативой передаче массива является использование ParamArray.Возврат массива из функции
Начиная с VBA версии 6 (Office 2000 и новее), процедура функции или процедура получения свойства может возвращать массив в качестве своего результата.
(В Office97 функция должна сохранять массив в Варианте и возвращать
Вариант.) Переменная, которая получает результат массива , должна быть динамическим массивом и
он должен иметь тот же тип данных, что и возвращаемый массив.Вы
не может объявить принимающий массив как массив вариантов для
принять массив любого типа. Так не пойдет. Принимающий массив должен
иметь тот же тип данных, что и возвращаемый массив, или это должен быть единственный вариант
(не массив вариантов).Например,
следующая функция загрузит массив с числами от Low до High и
вернуть массив как результат. Обратите внимание, что переменная
Прибытие в
AAATest
и тип возврата
LoadNumbers имеют один и тот же тип данных (Long).Sub AAATest () Dim Arr () до тех пор, пока Dim N As Long Arr = LoadNumbers (Low: = 101, High: = 110) Если IsArrayAllocated (Arr: = Arr) = True, то Для N = LBound (Arr) To UBound (Arr) Отладочная печать Arr (N) Следующий N Еще '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код на случай, если Arr не выделен. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Конец подписки Функция LoadNumbers (Low As Long, High As Long) As Long () '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Возвращает массив Long, содержащий 'числа от низкого до высокого.В 'количество элементов в возвращенном 'будет варьироваться в зависимости от 'значения Low и High. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Объявить ResultArray как динамический массив 'для изменения размера в зависимости от значений «Низкий и высокий. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim ResultArray () до тех пор, пока Dim Ndx As Long Дим Вал как долго '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Ensure Low <= High '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если низкий> высокий, то Функция выхода Конец, если '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Изменить размер массива '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' ReDim ResultArray (от 1 до (высокий - низкий + 1)) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Заполните массив значениями.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Val = Низкий Для Ndx = LBound (ResultArray) To UBound (ResultArray) ResultArray (Ndx) = Val Val = Val + 1 Следующий Ndx '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Вернуть массив. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' LoadNumbers = ResultArray () Конечная функцияОбратите внимание, что массив
Прибытие в
AAATest
имеет тот же тип данных (Long)
как массив, возвращаемый
LoadNumbers.Эти типы данных должны совпадать. Ты
не может объявить Arr
в AAATest
как массив вариантов для получения массива любого типа данных. Если вы это сделаете, вы получите
Ошибка компилятора « Can't Assign To Array ». Вы получите такой же компилятор
ошибка, если
Arr
статический массив. Массив, для которого установлено возвращаемое значение функции
должен быть динамическим массивом. Он может быть выделен, и в этом случае он будет
автоматически изменяет размер, чтобы сохранить массив результатов, либо увеличивая, либо
уменьшая его размер.Однако не требуется, чтобы принимающий массив был
выделено. Независимо от того, выделен ли принимающий массив, он
будет автоматически иметь размер, соответствующий размеру возвращаемого массива.Однако вы можете объявить принимающую переменную как
одиночный вариант. Например, вы можете использоватьDim Arr As Variant на месте Dim Arr () ДлинныйНапример, в следующем коде
Arr массив
будет изменен со 100 до 10, когда получит результат
LoadNumbers
функция.Sub AAATest () Dim Arr () до тех пор, пока Dim N As Long ReDim Arr (от 1 до 100) Debug.Print «ПЕРЕД LoadNumbers: количество элементов в Arr:» & CStr (UBound (Arr) - LBound (Arr) + 1) Arr = LoadNumbers (Low: = 101, High: = 110) Debug.Print «ПОСЛЕ LoadNumbers: количество элементов в Arr:» & CStr (UBound (Arr) - LBound (Arr) + 1) Конечный переводникФункция LoadNumbers (Low As Long, High As Long) As Long () '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'LoadNumbers 'Возвращает массив Long, содержащий числа 'между Низким и Высоким.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim ResultArray () до тех пор, пока Dim Ndx As Long Дим Вал как долго Если низкий> высокий, то Функция выхода Конец, если ReDim ResultArray (от 1 до (высокий - низкий + 1)) Val = Низкий Для Ndx = LBound (ResultArray) To UBound (ResultArray) ResultArray (Ndx) = Val Val = Val + 1 Следующий Ndx LoadNumbers = ResultArray () Конечная функцияЕсли принимающий массив имеет базовый индекс (LBound), который отличается
из массива, который он получает, принимающий массив примет новое базовое значение из
возвращенный массив.Например,Sub AAATest () Dim Arr () до тех пор, пока Dim N As Long '' '' '' '' '' '' '' '' '' '' '' '' ' 'Установите нижнюю и верхнюю 'границы Arr до 0 и 9 ' соответственно. '' '' '' '' '' '' '' '' '' '' '' '' ' ReDim Arr (от 0 до 9) Debug.Print «ПЕРЕД LoadNumbers: LBound:» & CStr (LBound (Arr)) & «UBound:» & CStr (UBound (Arr)) 'LoadNumbers использует нижнюю границу 1, а не 0 Arr = LoadNumbers (Low: = 101, High: = 110) Обратите внимание, что теперь LBound равен 1, а UBound - 10.Debug.Print «ПОСЛЕ LoadNumbers: LBound:» & CStr (LBound (Arr)) & «UBound:» & CStr (UBound (Arr)) Конечный переводникПриведенный выше код показывает, что граница LBound
Арр был
изменился с 0 на 1, LBound массива результатов объявлен и выделен
в LoadNumbers
процедура.Функция также может возвращать вариант, содержащий массив. Даже в этом случае
принимающий массив должен иметь тот же тип данных, что и массив, который хранится
в Варианте.Например,Sub AAATest () Dim Arr () до тех пор, пока Dim N As Long Arr = LoadNumbers (Low: = 101, High: = 110) Если IsArrayAllocated (Arr: = Arr) = True, то Для N = LBound (Arr) To UBound (Arr) Отладочная печать Arr (N) Следующий N Еще '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код на случай, если Arr не выделен. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Конец подписки Функция LoadNumbers (Low As Long, High As Long) Обратите внимание на вариант Variant, мы возвращаем Variant, а не Long () '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'LoadNumbers 'Возвращает вариант, содержащий массив, содержащий 'числа между Low и High.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim ResultArray () до тех пор, пока Dim Ndx As Long Дим Вал как долго Если низкий> высокий, то Функция выхода Конец, если ReDim ResultArray (от 1 до (высокий - низкий + 1)) Val = Низкий Для Ndx = LBound (ResultArray) To UBound (ResultArray) ResultArray (Ndx) = Val Val = Val + 1 Следующий Ndx LoadNumbers = ResultArray () Конечная функцияЕсли вызывающая процедура не знает, какой тип
данные будут в массиве, возвращаемом функцией, он может использовать вариант
переменная для хранения результата.Вариант будет содержать массив. С
эта версия LoadNumbers возвращает вариант, мы не можем делать никаких предположений
о том, что он может вернуть. Код должен проверять все непредвиденные обстоятельства
избежать непредвиденных ошибок времени выполнения.Sub AAATest () Dim Arr As Variant 'обратите внимание, что это объявлено как Varaint, а не как Long () Dim N As Long Arr = LoadNumbers (Low: = 101, High: = 110) '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что Arr - это массив. '' '' '' '' '' '' '' '' '' '' '' ' Если IsArray (Arr) = True, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что массив выделен.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если IsArrayAllocated (Arr: = Arr) = True, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Убедитесь, что Arr одномерный. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Если NumberOfArrayDimensions (Arr: = Arr) = 1, то '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Прокрутите возвращенный массив '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Для N = LBound (Arr) To UBound (Arr) '' '' '' '' '' '' '' '' '' '' '' '' 'Убедитесь, что Arr (N) является числовым.'' '' '' '' '' '' '' '' '' '' '' '' Если IsNumeric (Arr (N)) = True, то Отладочная печать Arr (N) Еще Debug.Print «Arr (N) не является числовым». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код в случае, если Arr (N) не является числовым. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Следующий N Еще Debug.Print «Arr не одномерный». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'Код в случае, если Arr многомерный.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Конец, если Еще Debug.Print «Arr не выделяется». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код на случай, если Arr не выделен. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Еще Debug.Print «Arr не является массивом». '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Код на случай, если Arr не является массивом. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Конец, если Конец подпискиФункция LoadNumbers (Low As Long, High As Long) в качестве варианта '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'LoadNumbers 'Возвращает вариант, содержащий массив, содержащий 'числа между Low и High.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim ResultArray () до тех пор, пока Dim Ndx As Long Дим Вал как долго Если низкий> высокий, то Функция выхода Конец, если ReDim ResultArray (от 1 до (высокий - низкий + 1)) Val = Низкий Для Ndx = LBound (ResultArray) To UBound (ResultArray) ResultArray (Ndx) = Val Val = Val + 1 Следующий Ndx LoadNumbers = ResultArray () Конечная функцияКак видите, использование вариантов для хранения массивов дает
у вас значительно больше гибкости, но это также оставляет больше места для ошибок
или неверные данные.Если вы используете варианты, ваш код должен содержать процедуры проверки ошибок.
чтобы убедиться, что вы имеете дело с ожидаемым типом данных.Назначение массива массиву
К сожалению, VBA не позволяет назначать один массив другому массиву,
даже если размер и типы данных совпадают.
Например, следующий код будет , а не работать:Dim A (от 1 до 10) As Long Dim B (от 1 до 10) по длине 'загрузить B данными А = ВОднако вы можете назначить вариант, содержащий
в другой вариант.Следующий код является совершенно допустимым:Dim A As Variant Dim B как вариант Dim N As Long A = Массив (11, 22, 33) В = А Debug.Print "IsArray (B) =" & CStr (IsArray (B)) Для N = LBound (B) To UBound (B) Отладка. Печать B (N) Далее NЕсли нужно передать содержимое одного массива в
другой, вы должны пройти по массиву поэлементно:Dim A (от 1 до 3) до тех пор, пока Dim B (от 0 до 5) до тех пор, пока Dim NdxA As Long Dim NdxB As Long А (1) = 11 А (2) = 22 А (3) = 33 NdxB = LBound (B) Для NdxA = LBound (A) To UBound (A) Если NdxB <= UBound (B), то B (NdxB) = A (NdxA) Еще Выход для Конец, если NdxB = NdxB + 1 Следующий NdxA Для NdxB = LBound (B) To UBound (B) Отлаживать.Печать B (NdxB) Далее NdxBПриведенный выше код передает содержимое массива A
в массив B. Он делает это успешно, даже если A и B имеют разные LBounds,
и завершит цикл UBound of B превышен, что будет
случай, если A содержит больше элементов, чем B. Если A содержит меньше элементов
чем B, неиспользуемые элементы B останутся нетронутыми. Если хотите
убедитесь, что B «чистый», прежде чем переносить на него элементы A, используйте
Оператор стирания и, если B - динамический массив,
Верните его в исходное состояние
размер, как показано ниже:Dim SaveLBound As Long Тусклое сохранение СохранитьLBound = LBound (B) SaveUBound = UBound (B) Стереть B Если IsArrayDynamic (Arr: = B) = True, то ReDim B (SaveLBound, SaveUBound) Конец, еслиМногомерные массивы
До сих пор во всех описанных процедурах и методах использовались одномерные массивы.Так что насчет многомерных массивов? Короткий ответ:
те же правила и методы, которые применяются к одномерным массивам, применяются к
многомерные массивы. Нафункции
Для страницы массивов VBA есть функция с именем
NumberOfArrayDimensions
который вернет количество измерений массива. (Возвращает 0 для
нераспределенные динамические массивы). Вы можете использовать эту функцию для определения
количество измерений статического или динамического массива.Вы можете пройти
многомерный массив в процедуру, как показано в приведенном ниже коде.Sub AAATest () Dim N As Long Дим-сумма на всю длину '' '' '' '' '' '' '' '' '' '' '' '' 'Объявить динамический массив '' '' '' '' '' '' '' '' '' '' '' ' Dim Arr () до тех пор, пока '' '' '' '' '' '' '' '' '' '' '' '' 'Размер массива на двоих ' Габаритные размеры. '' '' '' '' '' '' '' '' '' '' '' '' ReDim Arr (от 1 до 2, от 1 до 3) '' '' '' '' '' '' '' '' '' '' '' '' «Внесите некоторые ценности. '' '' '' '' '' '' '' '' '' '' '' '' Arr (1, 1) = 1 Arr (1, 2) = 2 Arr (1, 3) = 3 Arr (2, 1) = 4 Arr (2, 2) = 5 Arr (2, 3) = 6 '' '' '' '' '' '' '' '' '' '' '' '' ' SumMulti вернет 'сумма элемента в '1- или 2-мерный массив.'' '' '' '' '' '' '' '' '' '' '' '' ' Сумма = SumMulti (Приб .: = Приб.) Отладка. Печать суммы Конец подписки Функция SumMulti (Arr () до тех пор) до тех пор, пока Dim N As Long Dim Ndx1 As Long Dim Ndx2 As Long Dim NumDims As Long Dim Total As Long '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Получите количество измерений массива. 'NumberOfArrayDimensions вернет 0 'если массив не выделен. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' NumDims = NumberOfArrayDimensions (Arr: = Arr) Выберите Case NumDims Случай 0 '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'нераспределенный массив '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' SumMulti = 0 Функция выхода Дело 1 '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'одномерный массив '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Для N = LBound (Arr) To UBound (Arr) Итого = Итого + Прибыль (N) Следующий N Случай 2 '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '2-мерный массив '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Для Ndx1 = LBound (Arr, 1) To UBound (Arr, 1) Для Ndx2 = LBound (Arr, 2) To UBound (Arr, 2) Итого = Итого + Arr (Ndx1, Ndx2) Далее Ndx2 Далее Ndx1 Case Else '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' «Слишком много измерений.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' MsgBox «SumMulti работает только с 1 или 2-мерными массивами». Итого = 0 Конец Выбрать '' '' '' '' '' '' '' '' ' 'вернуть сумму '' '' '' '' '' '' '' '' ' SumMulti = Всего Конечная функцияФункции могут возвращать многомерные массивы точно так же, как
они могут одномерные массивы. Применяются те же правила: массив
получение результата должно быть динамическим массивом и должно быть
имеют тот же тип данных, что и возвращаемый массив.Например,Sub AAATest () '' '' '' '' '' '' '' '' '' '' '' 'Динамический массив для удержания ' результат. '' '' '' '' '' '' '' '' '' '' '' Тусклый ReturnArr () до тех пор, пока Dim Ndx1 As Long Dim Ndx2 As Long Dim NumDims As Long '' '' '' '' '' '' '' '' '' '' '' '' 'вызовите функцию, чтобы получить 'массив результатов. '' '' '' '' '' '' '' '' '' '' '' '' ReturnArr = ReturnMulti () NumDims = NumberOfArrayDimensions (Arr: = ReturnArr) Выберите Case NumDims Случай 0 '' '' '' '' '' '' '' '' '' 'нераспределенный массив '' '' '' '' '' '' '' '' '' Дело 1 '' '' '' '' '' '' '' '' '' '' '' '' 'одномерный массив '' '' '' '' '' '' '' '' '' '' '' '' Для Ndx1 = LBound (ReturnArr) To UBound (ReturnArr) Отлаживать.Распечатать ReturnArr (Ndx1) Далее Ndx1 Случай 2 '' '' '' '' '' '' '' '' '' '' '' '' ' 'двумерный массив '' '' '' '' '' '' '' '' '' '' '' '' ' Для Ndx1 = LBound (ReturnArr, 1) To UBound (ReturnArr, 1) Для Ndx2 = LBound (ReturnArr, 2) To UBound (ReturnArr, 2) Debug.Print ReturnArr (Ndx1, Ndx2) Далее Ndx2 Далее Ndx1 Case Else '' '' '' '' '' '' '' '' '' '' ' 'слишком много измерений '' '' '' '' '' '' '' '' '' '' ' Конец Выбрать Конец подписки Функция ReturnMulti () As Long () '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' 'Возвращает многомерный массив.'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Dim A (от 1 до 2, от 1 до 3) как долго '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'введите некоторые значения. '' '' '' '' '' '' '' '' '' '' '' '' '' '' А (1, 1) = 100 А (1, 2) = 200 А (1, 3) = 300 А (2, 1) = 400 А (2, 2) = 500 А (2, 3) = 600 ReturnMulti = A () Конечная функцияЦикл по массивам Вы могли заметить, что при просмотре массивов весь приведенный выше код использует LBound (Arr) и UBound (Arr) в качестве нижнего и верхнего пределов индекс цикла.Это самый безопасный способ перебрать массив. Это правильно установит границы переменной индекса цикла независимо от размера массива, и независимо от настройки модуля Option Base. Хорошая практика программирования диктует, что вы должны использовать LBound и UBound, а не жестко кодировать нижнюю и верхние значения индекса цикла. Это немного больше печатает, но гарантирует, что весь массив будет пройден по циклу, и позволит избежать ошибок времени выполнения Subscript Out Of Range .Использование массивов - это мощный прием в VBA, а передача и возврат массивов в функцию и из функции только расширяет диапазон возможностей вашего кода.Правильное понимание того, как передавать массивы между процедурами, имеет решающее значение для успешного использования массива в ваших приложениях.Передача массивов в качестве аргументов
Учебные пособия по VBScript - Учебные примеры Херонга
∟ «Функциональные» и «вспомогательные» процедуры
∟Передача массивов как аргументов
В этом разделе представлен учебный пример того, как передать массив в качестве аргументов по ссылке на обратные позиции всех элементов в массиве, заданном в качестве аргумента.
Как я упоминал ранее, массивы также могут передаваться как аргументы. Если массив передается по ссылке,
процедура работает с тем же массивом, что и вызывающий код. Если массив передается по значению,
процедура работает с независимой копией исходного массива в вызывающем коде.Вот пример кода использования массива в качестве аргумента, function_reverse_array.html:
Вот результат:
Тест 1: обращение литерала данных Ошибка: вы не даете массив. Тест 2: обращение массива Before Sub: Птица Кошка Собака Рыба Кролик After Sub: Кролик Рыба Собака Кошка ПтицаМоя функция "ReverseArray" работала отлично. Вы можете использовать его как служебную функцию для своего приложения.
Содержание
Об этой книге
Введение в VBScript - Visual Basic Scripting Edition
Вариантный тип данных, подтипы и литералы
Арифметические операции
Числовые операции сравнения и логические операции
Строковые операции - конкатенация и сравнение
Объявление переменных и заявление о назначении
Выражение и порядок выполнения операций
Синтаксис операторов и типы операторов
Тип данных массива и соответствующие утверждения
Ссылки на массивы и заявления о назначении массивов
Условные утверждения - «Если... Затем »и« Выбрать дело »
Операторы цикла - «For», «While» и «Do»
► «Функциональные» и «вспомогательные» процедуры
Что такое процедура?
Оператор «Функция» и вызов функции
Функция Пример процедуры
Оператор "Sub" и вызов подпрограммы
Sub (подпрограмма) Пример процедуры
Передача аргументов процедурам
Пример - передача аргументов по ссылке
Пример - передача аргументов по значению
►Передача массивов как аргументов
Объем переменных в процедурах
Пример - область действия переменной в процедурах
Встроенные функции
Проверка переменных, полученных в процедурах
Флаг обработки ошибок и объект «Err»
Соответствие и замена шаблона регулярного выражения
scrrun.dll - Библиотека DLL среды выполнения сценариев
Создание собственных классов
Веб-браузер IE с поддержкой VBScript
Сервер IIS ASP с поддержкой VBScript
WSH (хост сценариев Windows)
Список литературы
Полная версия в PDF / EPUB
Как передать массив из PowerApps в Power Automate
У вас есть следующие требования?
- Вы хотите передать массив из приложения Canvas в Power Automate
- Вы хотите передать массив из приложений, управляемых моделью, в Power Automate.
- Вам необходимо проанализировать данные JSON в приложении холста и выполнить дальнейшую обработку.
Если ваше требование похоже на это, этот блог может вам просто помочь. Это требование время от времени возникает, особенно для приложения Canvas. Итак, давайте посмотрим, как мы можем решить эту проблему. Для этого блога я создал простое приложение на холсте, которое показывает список учетных записей из CDS. Здесь я показываю пример с CDS. Однако примерный пример должен работать с любым другим источником данных.
Как видно на снимке экрана ниже, вы можете выбрать несколько учетных записей, а затем нажать кнопку «Отправить в Power Automate», чтобы отправить выбранные учетные записи в поток.
Перед тем, как мы создадим последовательность действий Power Automate, ниже приведен код событий «OnCheck» и «OnUncheck» флажка.
OnCheck:
Собрать (SelectedAccounts, ThisItem)
Вкл.
Удалить (SelectedAccounts, ThisItem)
Довольно просто. Я поддерживаю здесь коллекцию - « SelectedAccounts », которая используется для хранения учетных записей, выбранных пользователем. Что дальше? Нам нужно передать выбранные учетные записи в Power Automate.Итак, давайте создадим поток Power Automate.
Поток будет вызываться из приложения Canvas. Итак, совершенно очевидно, что триггером потока должны быть PowerApps.
На следующем шаге я использую шаг Initialize variable . И знаете что, у меня есть возможность выбрать « Array » в качестве типа переменной. Довольно просто, не правда ли? В конце концов, я собираюсь передать выбранные учетные записи из приложения Canvas и сохранить в этой переменной. И логически SelectedAccounts - это не что иное, как набор учетных записей.Значение переменной я спрошу у PowerApps.
Сохраняю сток. Теперь, когда мой поток создан, я подключаю его к обработчику события «OnSelect» кнопки, которую я ранее выделил в приложении Canvas. Но когда я пытаюсь добавить поток в свое приложение холста, я получаю следующую ошибку.
Причина этого в том, что тип данных Array не поддерживается приложениями Canvas. Я модифицирую поток, чтобы изменить тип данных переменной на «String». Теперь, когда я пытаюсь добавить поток обратно, я могу это сделать успешно.
Это хорошо. Но к тому, как пройти выбранные аккаунты. На самом деле это довольно просто. Мы будем использовать функцию JSON в приложениях холста для сериализации коллекции в JSON.
ArrayTestFlow.Run (JSON (SelectedAccounts, JSONFormat.IncludeBinaryData и JSONFormat.IgnoreUnsupportedTypes))
В обработчике событий OnSelect я вызываю поток со списком учетных записей, выбранных пользователем.
Когда я проверял свой поток, я мог видеть сериализованное значение JSON для выбранных мной учетных записей.
Вам может быть интересно, как разобрать этот JSON в потоке. Что ж, это довольно просто.