Обсуждение статьи "Основы программирования на MQL5 - Массивы" - страница 3

 
Ernie Gunning:

Хорошо, давайте попробуем английскую версию MQL.


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

Надеюсь, я смогу вам помочь! Код ниже работает для всех типов данных. Он будет работать и с объектами, но метод Contains (поиск) может не сработать. Я тестировал его только на типах (double, int, bool). Со строками тоже могут возникнуть проблемы, и код, возможно, придется расширить.



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




надеюсь, это кому-нибудь поможет


Пожалуйста, не принимайте во внимание мое предложение выше использовать динамический массив для любого типа данных. Уже объявлен общий CArrayList. Пожалуйста, используйте его. Я столкнулся с проблемой использования объектов, которая была решена в этой теме: https: //www.mql5.com/en/forum/358432.

Using CArrayList gives error
Using CArrayList gives error
  • 2020.12.20
  • www.mql5.com
Hi Guys, Thanks for your time. I'm struggling to use the CArrayList in the generics folder. Are these interfaces and classes complete...
 
Я уже прочитал несколько хороших статей от вас. Эта не стала исключением.
 

Похоже, ошибка в функции arrayResize(), в примере содержимое массива 1, 1, 3 при нормальной индексации не 1, 2, 3. См. этот пример:

//+------------------------------------------------------------------+
//|false.mq5 |
//|Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Пользовательская функция инициализации индикатора |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- отображение индикаторных буферов
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Пользовательская функция итерации индикатора|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   double ar[]; // Массив
ArrayResize(ar,2); // Подготовьте массив
ar[0]=1; // Установите значения
ar[1]=2; 
ArraySetAsSeries(ar,true); // Измените порядок индексации
ArrayResize(ar,3); // Увеличьте размер массива
ar[0]=3; // Установите значение для нового элемента массива
Alert(ar[0]," ",ar[1]," ",ar[2]); // Выведите значения массива
ArraySetAsSeries(ar,false);
Alert("Normal indexing: ", ar[0]," ",ar[1]," ",ar[2]); // Выведите значения массива
//--- возвращаем значение prev_calculated для следующего вызова
   return(rates_total);
  }
//+------------------------------------------------------------------+
В добавленной функции arraySetAsSeries(), похоже, затронута функция arrayresieze, см. этот пример:
//+------------------------------------------------------------------+
//|errorindex.mq5 |
//|Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Пользовательская функция инициализации индикатора |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- отображение индикаторных буферов
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Пользовательская функция итерации индикатора|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   double ar[]; // Массив
ArrayResize(ar,2); // Подготовьте массив
ar[0]=9; // Установите значения
ar[1]=8; 
ArrayResize(ar,6); // Увеличьте размер массива
Alert("Normal resize: ", ar[0]," ",ar[1]," ",ar[2]," ", ar[3], " ", ar[4], " ", ar[5]);
ArraySetAsSeries(ar,true); // Измените порядок индексации
ArrayResize(ar,4); // Увеличьте размер массива
ArraySetAsSeries(ar, false);
Alert("See the random element added: ", ar[0]," ",ar[1]," ",ar[2]," ", ar[3]);
ArraySetAsSeries(ar,true); // Измените порядок индексации 0
ar[0]=8; // Установите значение для нового элемента массива
Alert("Modify the first as serlies: ", ar[0]," ",ar[1]," ",ar[2]," ", ar[3]); // Выведите значения массива
//--- возвращаем значение prev_calculated для следующего вызова
   return(rates_total);
  }
//+------------------------------------------------------------------+

Шаги:

1. ar = {}
2. ar = {9, 8}

3. ar = {9, 8, 0, 8, 0, 0}

4. Установите в качестве серии true:

ar = {0, 0, 8, 0, 8, 9}

5. Измените размер до 4

ar = {0, 0, 8, 0}

6. Установите в качестве серии false:

ar = {0, 8, 0, 0}

7. Установите в качестве серии true:

ar = {0, 0, 8, 0}

8. Измените первый элемент a[0]

ar = {8, 0, 8, 0}


Я не знаю, что такое resize массива (3 -5) берет значения и копирует в новые позиции, 6 вперед берет случайные значения, я думаю. Я предпочитаю сначала выполнить resize(), а затем setasseries(), как здесь:

//+------------------------------------------------------------------+
//|indexingarraytest.mq5 |
//|Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Пользовательская функция инициализации индикатора |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- отображение индикаторных буферов
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Пользовательская функция итерации индикатора|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   double ar[]; // Массив
ArrayResize(ar,2); // Подготовьте массив
ar[0]=1; // Установите значения
ar[1]=2;
ArrayResize(ar,3); // Увеличьте размер массива
Alert("Redimension to 3 normal: ", ar[0], " ", ar[1], " ", ar[2]); 
ArraySetAsSeries(ar,true); // Измените порядок индексации
Alert("Redimension to 3 series: ", ar[0], " ", ar[1], " ", ar[2]); 
ar[0]=8; // Установите значение для нового элемента массива
Alert("Change the first element: ", ar[0]," ",ar[1]," ",ar[2]); // Выведите значения массива
ArraySetAsSeries(ar, false);
Alert("Normal renew: ", ar[0]," ",ar[1]," ",ar[2]); // Выведите значения массива
//--- возвращаем значение prev_calculated для следующего вызова
   return(rates_total);
  }
//+------------------------------------------------------------------+