Errori, bug, domande - pagina 1438

 
Сергей Таболин:

E quando la questione della dimensione dell'array sarà risolta, penso ancora che dovreste vedere quali valori hanno pr_open e pr_close quando vengono chiamati per la prima volta.


P./S.: Non sono inizializzati qui:

...
int            buf_lup[], buf_ldn[];
...
void OnTick()
{
   int      lup, ldn, sup, sdn;
   int      sum_up, sum_dn;
   double   pr_open, pr_close;

.........

      ldn = 0;
      sup = 0;
      sdn = 0;
      sum_up = 0;
      sum_dn = 0;

.........

               buf_ldn[ldn] = (int)((pr_open - pr_close) / Point()); // ОШИБКА тут
               sum_dn += buf_ldn[ldn++];

........
}

e non si può vedere nel codice che qualcosa è assegnato a loro.

Anche se forse la loro inizializzazione è nascosta da qualche parte in questi:

.........

linee di codice che avete nascosto.

 
Сергей Таболин:

Esattamente ))) Non c'è nessun problema con loro.

In generale, è un po' scomodo tenere traccia della dimensione di un array dinamico tutto il tempo... Bisogna sapere quanto pesa. Che senso ha, allora? ....

Il punto è che se non si sa in anticipo quanti elementi saranno messi dentro, non c'è bisogno di dichiarare un array statico di una dimensione maggiore garantita (con molto margine, in modo che ci stia in ogni caso) e sprecare memoria. Semplicemente, quando nuovi dati devono essere aggiunti all'array, si aumenta dinamicamente la sua dimensione.
 
Сергей Таболин:

In linea di principio, questo è comprensibile. L'unica cosa che non capisco è perché questo array non può essere incrementato automaticamente.

Perché non si poteva fare così? Non è una mia idea )))) Questo è esattamente il modo in cui ho cercato di usare un array dinamico...

Inoltre devo salvare l'indice... Non va bene...

Chi dice che non si può ingrandire dinamicamente?

Qui per aiutarvi

ArrayResize

Устанавливает новый размер в первом измерении массива



int  ArrayResize( 
   void&  array[],              // массив, переданный по ссылке 
   int    new_size,             // новый размер массива 
   int    reserve_size=0        // резервное значение размера (избыточное) 
   );
 

Параметры

array[]

[out]  Массив для изменения размеров.

new_size

[in]  Новый размер для первого измерения.

reserve_size=0

[in]  Необязательный параметр. Размер для дополнительного резерва.

Возвращаемое значение

При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры.

Примечание

Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в качестве индикаторных буферов функцией SetIndexBuffer(). Для индикаторных буферов все операции по изменению размера производит исполняющая подсистема терминала.

Общее число элементов в массиве не может превышать 2147483647.

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



ArrayResize(arr,1000,1000); 
for(int i=1;i<3000;i++) 
   ArrayResize(arr,i,1000);
 

В данном случае произойдёт 2 перераспределения памяти, один раз до входа в цикл на 2000 элементов, при этом размерность массива будет установлена в 1000 и второй при i равной 2000. Если третий параметр опустить, то произойдёт 2000 физических перераспределения памяти и это замедлит выполнение программы.

Dovremmo fare una guida su come usare l'aiuto )))))))))))))))))))))

 
Сергей Таболин:

In linea di principio, questo è comprensibile. Quello che non è chiaro è perché questo array non può essere incrementato automaticamente.

int arr[];

arr[] = 1;
arr[] = 9;
arr[] = 3;
....

Perché non si poteva fare così? Non è una mia idea )))) Questo è esattamente il modo in cui ho cercato di usare un array dinamico...

Inoltre devo salvare l'indice... Non va bene...

Non capisco cosa stavate cercando di fare in questo codice.

Qui, vi ho abbozzato un piccolo esempio che mostra a cosa servono gli array dinamici e come usarli.

   // динамический массив строк, в который поместим считанные из файла "FileName.txt" строки,
   // количество строк в файле нам неизвестно
   string Strings[];
   ArrayResize(Strings, 0, 20);   // сейчас это массив нулевой длины
   
   // открываем текстовый файл для чтения
   int hFile = FileOpen("FileName.txt", FILE_READ|FILE_TXT);
   
   if(hFile != INVALID_HANDLE)
   {
      // каретку в начало файла
      FileSeek(hFile, 0, SEEK_SET);
      
      // вспомагательные переменные
      string sString;
      int nTotalStrings = 0;
      
      // читаем файл построчно
      while(!FileIsEnding(hFile) && !IsStopped())
      {
         // считываем очередную строку
         sString = FileReadString(hFile);
         
         // добавляем считанную строку в массив, предварительно увеличив его размер на 1
         if(sString != "")
         {
            nTotalStrings++;
            ArrayResize(Strings, nTotalStrings, 20);
            Strings[nTotalStrings-1] = sString;
         }
      }
      
      // уходя, гасите свет
      FileClose(hFile);
   }
   
   // выведем считанные строки в журнал для проверки
   for(int i = 0; i < ArraySize(Strings); i++)
      Print(Strings[i]);
 
Сергей Таболин:

Non capisco perché questo array non possa essere incrementato automaticamente.

Perché gli sviluppatori del linguaggio sono stati cresciuti con Syakh, e questo ostacola gravemente la transizione di MQL da hardcore SI-like a popsy PHP/JS-like. Nel PHP plebeo si assegna semplicemente un nuovo valore e l'array regola automaticamente la sua dimensione. MQL fa sentire al codificatore la sua importanza. Quindi prendete una pala e godetevi il fatto di far parte di una casta selezionata di professionisti
 
Сергей Таболин:

Questo è, in linea di principio, un semplice esempio di come un array dinamico dovrebbe normalmente essere riempito. Non scrivo in C da molto tempo, non ricordo, ma è così che si riempiono gli array in php! Tutto è logico e comprensibile. Se aggiungo un elemento a un array (arr[] = x), l'array viene automaticamente espanso, e l'elemento viene aggiunto alla fine dell'array. E non dobbiamo allungarlo da soli, e non dobbiamo specificare l'indice dell'elemento da soli. Ma qui dobbiamo fare movimenti assolutamente inutili:

la differenza è evidente...

Secondo me, è strano, per non dire altro ))))

Bene, allora prendi una pala e scrivi la tua implementazione degli array dinamici, che funzionerà esattamente in quel modo, cosa ti ferma? )) Anche se, per sovraccaricare [] per l'assegnazione MKL non permette, non è abbastanza hardcore. ))
 
Сергей Таболин:

Questo è, in linea di principio, un semplice esempio di come un array dinamico dovrebbe normalmente essere riempito. Non scrivo in C da molto tempo, non mi ricordo, ma è così che si riempiono gli array in php! Tutto è logico e comprensibile. Se aggiungo un elemento a un array (arr[] = x), l'array viene automaticamente espanso, e l'elemento viene aggiunto alla fine dell'array. E non dobbiamo allungarlo da soli, e non dobbiamo specificare l'indice dell'elemento da soli. Ma qui dobbiamo fare movimenti assolutamente inutili:

la differenza è evidente...

Lo trovo strano, a dir poco ))))

Chi ci impedisce di usare OOP e di implementare una sintassi simile?

#property strict

/*
enum TestEnum
{
  zero,
  one,
  two,
  three,
  four,
  five,
  six,
  seven,
  eight,
  nine,
  ten,
  eleven,
  twelve,
  thirteen,
  fourteen,
  fitteen
};
*/

template <typename T>
class RubbArray
{
  private:
    T data[];
    
  protected:
    void add(T d)
    {
      int n = ArraySize(data);
      ArrayResize(data, n + 1);
      data[n] = d;
    }
    
  public:
    
    T operator[](int i) const
    {
      return data[i];
    }
    
    RubbArray *operator<<(T d)
    {
      add(d);
      return GetPointer(this);
    }

    T operator=(T d)
    {
      add(d);
      return d;
    }

    void operator=(const RubbArray &d)
    {
      int i, n = d.size();
      ArrayResize(data, n);
      for(i = 0; i < n; i++)
      {
        data[i] = d[i];
      }
    }

    T operator>>(int i)
    {
      T d = this[i];
      ArrayCopy(data, data, i, i + 1);
      ArrayResize(data, ArraySize(data) - 1);
      return d;
    }
    
    int size() const
    {
      return ArraySize(data);
    }
    
    void print() const
    {
      int i, n = ArraySize(data);
      string s;
      for(i = 0; i < n; i++)
      {
        s += (string)data[i] + ",";
      }
      Print(s);
    }
};

void OnStart()
{
  //RubbArray<TestEnum> d;
  RubbArray<double> d, d2;
  d << 5 << 7;
  d = 10;
  d << 15;
  d.print();
  Print(d[1]);
  double x = d >> 1;
  d2 = d;
  d2.print();
}
 
Alexander Puzanov:
Poiché gli sviluppatori del linguaggio sono stati cresciuti con Syakh, questo ostacola gravemente la transizione di MQL da hardcore SI-like a poppy PHP/JS-like. Nel PHP plebeo si assegna semplicemente un nuovo valore e l'array regola automaticamente la sua dimensione. MQL fa sentire al codificatore la sua importanza. Quindi, prendete una pala e godetevi l'essere un membro dei pochi professionisti selezionati.
Secondo me, un semplice array non dovrebbe "aggiustare le sue dimensioni" senza che il programmatore ne sia consapevole. Se tale comportamento è necessario, bisogna scrivere una classe corrispondente. E poi si può usare un array "intelligente" senza problemi. E le strutture semplici, a cui l'array appartiene inizialmente, non devono avere "diritti di decisione indipendenti".
 
Quattro persone te l'hanno già detto: prendi una pala e scrivi il tuo corso, visto che ne hai così tanto bisogno. ))
 
Сергей Таболин:

"senza la conoscenza del programmatore" non funziona. È il programmatore che dà il comando "aggiungere un elemento alla fine dell'array" (arr[] = x). E la matrice non ha "diritti di decisione indipendenti". Solo eseguendo il comando del programmatore aumenta la sua dimensione, sollevando così il programmatore dal tenere traccia di questa stessa dimensione. )))

Come dimostra la mia esperienza, se il programmatore scrive qualcosa in un array contenente 10 elementi con indice 20, molto probabilmente significa che ha fatto un errore, e il programma dovrebbe generare un errore, ma non aumentare la dimensione dell'array, nascondendo così un'azione sospetta.

Tutti questi "array che modificano le dimensioni" hanno molti più problemi nel nascondere i potenziali errori che nella convenienza. Inoltre, e non dover tenere traccia della dimensione dell'array è anche una pratica potenzialmente pericolosa, che porta a bug difficili da risolvere.

Motivazione: