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

 
Очень полезная статья с хорошими объяснениями, спасибо Дмитрию Федосееву.
 
как вернуть массив из функции? нашёл пока обходной путь, но явно ж должен быть способ как это сделать "в лоб" ))
 
thejobber:
как вернуть массив из функции? нашёл пока обходной путь, но явно ж должен быть способ как это сделать "в лоб" ))

В лоб - никак... разве, что указатель на массив. Например:

CArrayDouble *Function(void);

Не в лоб, но вполне стандартный подход, как-то так, в таком разрезе:

void Function(double &_arr_out[]);
В общем, возвращаемый массив - это параметр-ссылка...
 

ага, спасибо... пытался просто сразу

return *х; по привычке, как на с++ ))

вместо

return GetPointer(х)

разобрался )) 

 
MetaQuotes Software Corp.:

Новая статья Основы программирования на MQL5: Массивы опубликована:

Автор: Дмитрий Федосеев

1 Вопрос:

#define  SIZE_X 3;

(...)

int ArrayName[SIZE_X];

Компилятор запрещает такую конструкцию. Почему?

 
Большое спасибо за этот развернутый обзор
 
#import "dll.dll"
  double qwerty(double &q[]);
#import

Вот я делаю dll я хочю ей передать указатель на массив

Но не могу понять как это сделать.

Чтото не так.


Мне нужно некий аналог с++


double qwerty(double *q);

double *q;

q = new double [100];

qwerty(q);


Как это сделать на MQL5...

 
В mql какой есть массив, такой и есть, с ним ничего не сделаете. Никаких проблем не должно быть. Ошибка где-то рядом в вашей dll. Может быть в dll еще стоит передавать размер массива.
 

Thanks for your code it saved me some time to write. I ried to used the MQL5 Array object (double,int etc.) and I just got frustrated. I came to your post and found your code to resize the arrays that was awesome thanks. I modified your code to cater for any data type. Just dont try to use the Contains (Search method) method for objects as it might not work as objects might be references, not sure I haven't tested this. I'm trying to recreate C# inside MQL5 hence the abbreviations are similar :)


God Bless !!!



// + ----------------------------------------------- ------------------- + 


// | 
CDynamicArray.mqh | 


// | 
Integer | 


// | 
https://login.mql5.com/ru/users/Integer | 


// + ----------------------------------------------- ------------------- + 


#property 

copyright  

"Integer" 


#property 

link  

"https://login.mql5.com/en/users/Integer" 


// + - -------------------------------------------------- --------------- + 


// | 
| 


// + ----------------------------------------------- ------------------- + 


template 

< 

typename 

 T> 


class 

 CDynamicArray 


  { 


private 

 : 
   

int 

                m_ChunkSize;     

// Chunk size 
   

int 

                m_ReservedSize; 

// Actual size of the array 
   

int 

                m_Size;         

// Number of active elements in the array 


public 

 : 


   T Element [];       

// The array proper. 
It is located in the public section, 
                                     

// so that we can use it directly, if necessary 
   

// + --------------------------- --------------------------------------- + 
   

// | 
Constructor | 
   

// + ----------------------------------------------- ------------------- + 
   

void 

 CDynamicArray ( 

int 

 ChunkSize = 

1024 

 ) 


     { 


      m_Size = 

0 

 ;                             

// Number of active elements 


       m_ChunkSize = ChunkSize;               

// Chunk size 


       m_ReservedSize = ChunkSize;             

// Actual size of the array 
      

ArrayResize 

 (Element, m_ReservedSize); 

// Prepare the array 


      } 
   

// + ----------------------------------------- ------------------------- + 
   

// | 
Function for adding an element at the end of array | 
   

// + ----------------------------------------------- ------------------- + 
   

void 

 Add (T Value) 


     { 


      m_Size ++; 

// Increase the number of active elements 
      

if 

 (m_Size> m_ReservedSize) 


        { 

// The required number is than the actual array size 


          m_ReservedSize + = m_ChunkSize; 

// Calculate the new array size 
         

ArrayResize 

 (Element, m_ReservedSize); 

// Increase the actual array size 


         } 


      Element [m_Size- 

1 

 ] = Value; 

// Add the value 


      } 
     
     

void 

 Set ( 

int 

 index, T Value) 


     { 


      m_Size ++; 

// Increase the number of active elements 
      

if 

 (m_Size <index) 


        { 
         

return 

 ; 


        } 


      Element [index] = Value; 

// Add the value 


      } 
   

// + ----------------------------------------- ------------------------- + 
   

// | 
Function for getting the number of active elements in the array | 
   

// + ----------------------------------------------- ------------------- + 
   

int 

 Count () 


     { 
      

return 

 (m_Size); 


     } 
   


   T 

operator 

 [] ( 

const  

int 

 index) 

const 

 { 

return 

 Element [index]; 
} 
   
   

bool 

Contains (T itemToFind) 


   { 
      

for 

 ( 

int 

 i = 

0 

 ; i <Count (); i ++) 


        { 
            

if 

 (Element [i] == itemToFind) 


            { 
               

return  

true 

 ; 


            } 


        } 
        
      

return  

false 

 ; 


   } 
   
   

int 

 IndexOf (T itemToFind) 


   { 
      

for 

 ( 

int 

 i = 

0 

 ; i <Count (); i ++) 


        { 
            

if 

 (Element [i] == itemToFind) 


            { 
               

return 

 i; 


            } 


        } 
        
      

return 

 - 

1 

 ; 


   } 


  }; 


// + ----------------------------------------------- ------------------- + 

Then you can declare them like so:

CDynamicArray 

< 

int 

> 

  *Tickets; 


CDynamicArray 

< 

bool 

> 

 *FixedSLUsed; 


CDynamicArray 

< 

bool 

> 

 *PrevBarSLUsed; 

and create them like:

                        Tickets = 

new 

 CDynamicArray< 

int 

>(); 


                        FixedSLUsed = 

new 

 CDynamicArray< 

bool 

>(); 


                        PrevBarSLUsed = 

new 

 CDynamicArray< 

bool 

>(); 

and in the code you use them like a normal class:



int 

 ticket = 

PositionGetInteger 

 ( 

POSITION_TICKET 

 ); 


int 

 index; 


if 

 (!Tickets.Contains(ticket)) // If Ticket Object does NOT contains ticket then we go into the if 


{ 


        Tickets.Add(ticket); 


        FixedSLUsed.Add( 

false 

); 


        PrevBarSLUsed.Add( 

false 

); 


} 
      


index = Tickets.IndexOf(ticket);   
 

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


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

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


//+------------------------------------------------------------------+
//|CDynamicArray.mqh |
//|Целое число |
//| https://login.mql5.com/ru/users/Integer |
//+------------------------------------------------------------------+
#property copyright "Integer"
#property link "https://login.mql5.com/ru/users/Integer"
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
template <typename T>
class CDynamicArray
  {
private:
   int               m_ChunkSize;    // Размер куска
   int               m_ReservedSize; // Фактический размер массива
   int               m_Size;         // Количество активных элементов в массиве
public:
   T                 Element[];      // Собственно массив. Он находится в разделе public, 
                                     // чтобы мы могли использовать его напрямую, если потребуется
   //+------------------------------------------------------------------+
   //| Конструктор|
   //+------------------------------------------------------------------+
   void CDynamicArray(int ChunkSize=1024)
     {
      m_Size=0;                            // Количество активных элементов
      m_ChunkSize=ChunkSize;               // Размер куска
      m_ReservedSize=ChunkSize;            // Фактический размер массива
      ArrayResize(Element,m_ReservedSize); // Подготовьте массив
     }
   //+------------------------------------------------------------------+
   //| Функция для добавления элемента в конец массива |
   //+------------------------------------------------------------------+
   void Add(T Value)
     {
      m_Size++; // Увеличьте количество активных элементов
      if(m_Size>m_ReservedSize)
        { // Искомое число больше, чем реальный размер массива
         m_ReservedSize+=m_ChunkSize; // Вычислите новый размер массива
         ArrayResize(Element,m_ReservedSize); // Увеличиваем фактический размер массива
        }
      Element[m_Size-1]=Value; // Добавьте значение
     }
     
     void Set(int index, T Value)
     {
      m_Size++; // Увеличьте количество активных элементов
      if(m_Size<index)
        { 
         return;
        }
      Element[index]=Value; // Добавьте значение
     }
   //+------------------------------------------------------------------+
   //| Функция для получения количества активных элементов в массиве|
   //+------------------------------------------------------------------+
   int Count()
     {
      return(m_Size);
     }
   
   T operator[](const int index) const { return Element[index]; }
   
   bool Contains(T itemToFind)
   {
      for(int i=0;i<Count();i++)
        {
            if(Element[i] == itemToFind)
            {
               return true;
            }
        }
        
      return false;
   }
   
   int IndexOf(T itemToFind)
   {
      for(int i=0;i<Count();i++)
        {
            if(Element[i] == itemToFind)
            {
               return i;
            }
        }
        
      return -1;
   }
  };
//+------------------------------------------------------------------+


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


//Я объявил их в своем классе следующим образом
   CDynamicArray<int> *Tickets;
   CDynamicArray<bool> *FixedSLUsed;
   CDynamicArray<bool> *PrevBarSLUsed;


// Затем я объявил их в методах своего класса следующим образом

   Tickets = new CDynamicArray<int>();
   FixedSLUsed = new CDynamicArray<bool>();
   PrevBarSLUsed = new CDynamicArray<bool>();

// и я использовал их в методах моего класса следующим образом:
      int ticket = PositionGetInteger(POSITION_TICKET);
      int index;
      if(!Tickets.Contains(ticket))
      {
         Tickets.Add(ticket);
         FixedSLUsed.Add(false);
         PrevBarSLUsed.Add(false);
      }
      
      index = Tickets.IndexOf(ticket);  
//больше кода было удалено



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