MQL5 – Массивы

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

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

А как массив может применяться в торговых роботах? Давайте разберемся.


Предыдущие уроки


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

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

По сути, массив – это индексированная совокупность однотипных данных:

int a[50]; // Одномерный массив из 50 целых чисел.
double m[7][50]; // Двухмерный массив из семи массивов, 
                          // каждый из которых состоит из 50 чисел.
MyTime t[100]; // массив, содержащий элементы типа MyTime. 

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

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

Индексом массива может быть только целое число. Допускаются не более чем четырехмерные массивы. Нумерация элементов массива начинается с 0, соответственно, последний элемент одномерного массива имеет номер на единицу меньший, чем размер массива, то есть обращение к последнему элементу массива из 50 целых чисел будет выглядеть как a[49]. То же самое относится и к многомерным массивам – индексация одного измерения производится от 0 до «размер измерения» — 1. Последний элемент двумерного массива из примера будет выглядеть как m[6][49]. С этим нужно быть внимательным, так как при доступе за пределы массива исполняющая подсистема сгенерирует критическую ошибку и выполнение программы будет остановлено.

Работа с массивами

Давайте создадим массив:

int my_array[4] = {1, 3, 4, 7};

Инициализация массива производится с помощью фигурных скобок {}, внутри которых через запятую находятся значения для инициализации. Кстати, при такой записи указывать размерность массива не обязательно:

int my_array[] = {1, 3, 4, 7};

Можно сделать и так:

int my_array_2[4] = {0};

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

Чтобы получить значение конкретного элемента, достаточно просто обратиться к массиву, указав индекс интересующего элемента. Как вы помните, индексация начинается с нуля. Например,  my_array[0] в нашем примере будет равно 1, my_array[3] равно 7, а за запись my_array[4] терминал вас отругает. Проверим:

Print( my_array[0] );
Print( my_array[1] );
Print( my_array[2] );
Print( my_array[3] );
Print( my_array_2[0] );
Print( my_array_2[1] );
Print( my_array_2[2] );
Print( my_array_2[3] );

Если мы сделаем так:

Print( my_array_2[4] );

то на этапе компиляции ошибок не будет, ругаться будет именно терминал – он даже подскажет, в каком месте кода есть ошибка. Но это происходит только тогда, когда у вас есть исходный файл с кодом. Если его нет, программу можно просто выкинуть.

Функции для работы с массивами

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

Итак, нам нужен массив с пятью элементами вместо четырех:

ArrayResize( my_array_2, 5);

Теперь, если мы вызовем:

Print( my_array_2[4] );

мы получим ошибку компилятора о том, что функция ArrayResize неприменима к статическим массивам. Статический массив – это массив, количество элементов которого заранее задано, как в нашем случае. Далее в программе размер массива не изменить.

При инициализации массива можно воспользоваться одноименной функцией:

int ArrayInitialize(
int array[], // инициализируемый массив
int value // значение, которое будет установлено
);

В данном примере мы инициализировали динамический массив типа int. Динамический – значит, мы можем изменять количество элементов в нем с помощью функции ArrayResize.

Можно использовать и такую запись для объявления динамического массива:

int my_array_3[];

Теперь мы можем задать новому массиву размерность:

ArrayResize( my_array_3, 4);

Тем не менее, при вызове

Print( my_array_3[4] );

у нас снова будет все та же ошибка. Это происходит потому, что в массиве всего 4 элемента. Если перед Print вызвать ArrayResize:

ArrayResize( my_array_3, 5 );

то ошибки уже не будет.

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

int a = 5;
ArrayResize( my_array_3, a );

Узнать размер массива легко с помощью функции ArraySize:

int ArraySize(
const void& array[] // проверяемый массив
);

Задачу выше можно решить следующим образом, особенно если мы не знаем, сколько элементов в массиве:

ArrayResize( my_array_3, ArraySize( my_array_3 ) + 1 );

Со статическим значением так не получится. Задавать значения конкретным элементам массива очень просто:

int ArraySize(
const void& array[] // проверяемый массив
);

Для печати массива в консоли можно использовать метод ArrayPrint:

void ArrayPrint(
const void& array[], // выводимый массив
uint digits=_Digits, // количество десятичных знаков после запятой
const string separator=NULL, // разделитель между значениями полей структуры
ulong start=0, // индекс первого выводимого элемента
ulong count=WHOLE_ARRAY, // количество выводимых элементов
ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN 
);

Таким образом,

ArrayPrint(my_array_3);

выведет наш массив на печать.

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

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

Теперь разберемся с многомерными массивами. Объявим многомерный массив:

int my_array_4[2][3];

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

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

int my_array_5[];
ArrayResize( my_array_5, 227 );
for (int i = 0; i < ArraySize( my_array_5 ); i++) {
	Print ( my_array_5[i] );
}

Этот код выведет на печать каждый из 227 элементов массива.

На этом все, всем пока!

Тема на форуме

С уважением, Дмитрий аkа Silentspec
Tlap.com

Уроки по MQL5 , , ,