Ошибки, баги, вопросы - страница 1438

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

А когда вопрос с размером массива разрешится, всё-таки, полагаю, стоит посмотреть, какие значения у pr_open и pr_close при первом обращении к ним.


P./S.: Тут они не проинициализированы:

...
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++];

........
}

и не видно в коде, чтобы им что-то присваивалось.

Хотя может их инициализация где-то в этих:

.........

строчках кода спрятана у вас.

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

Именно ))) В них проблемм нет.

А вообще, как-то это неудобно постоянно следить за размерностью динамического массива...  Нужно знать сколько он весит. А смысл тогда в нём какой? ....

Смысл в нём такой, что если заранее неизвестно количество элементов, которые в него будут помещены, не нужно объявлять статический массив гарантированно большего размера (с большим запасом, чтобы на все случаи жизни хватило) и понапрасну расходовать память. Просто по мере появления новых данных, которые нужно добавить в массив, динамически увеличиваете его размер.
 
Сергей Таболин:

В принципе, это понятно. Не понятно только почему нельзя увеличивать этот массив автоматически?

Ну вот почему так нельзя было сделать? Это не я придумал ))) Именно так я и пытался использовать динамический массив...

Плюс дополнительно нужно индекс сохранять... Не фонтан... 

Кто сказал что нельзя увеличить динамически ???

Вот Вам в помощь

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 физических перераспределения памяти и это замедлит выполнение программы.

 

Надо сделать справку о том как пользоваться справкой ))))))))))))))))))))) 

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

В принципе, это понятно. Не понятно только почему нельзя увеличивать этот массив автоматически?

int arr[];

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

Ну вот почему так нельзя было сделать? Это не я придумал ))) Именно так я и пытался использовать динамический массив...

Плюс дополнительно нужно индекс сохранять... Не фонтан... 

Я не понял, что вы пытались сделать в этом коде.

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

   // динамический массив строк, в который поместим считанные из файла "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]);
 
Сергей Таболин:

Не понятно только почему нельзя увеличивать этот массив автоматически?

Патамушта разработчики языка воспитаны на Сях и это сильно тормозит переход MQLа от хардкорной СИ-образности к попсовому PHP/JS-подобию. Это в плебейском PHP достаточно присвоить новое значение и массив сам подстроит свой размер, а MQL даёт прочувствовать насколько важная персона кодер. Так что берите лопату и наслаждайтесь причастностью к касте избранных профессионалов
 
Сергей Таболин:

Это, в принципе, простой пример как по нормальному должен заполняться динамический массив. На С я очень давно не писал, не помню, но в php массивы именно так и заполняются! Всё логично и понятно. Если я добавляю элемент в массив (arr[] = x), то массив автоматически увеличивается, и элемент добавляется в конец массива. И не нужно самому растягивать его, и не нужно самому указывать индекс элемента. Здесь же нам приходится делать совершенно лишние движения:

разница очевидна...

на мой взгляд это, по меньшей мере, странно ))) 

Ну, тогда берите лопату и пишите свою реализацию динамических массивов, которые будут работать именно так, что мешает? )) Правда, перегрузить [] для присваивания МКЛ не позволит, хардкорности не хватит. ))
 
Сергей Таболин:

Это, в принципе, простой пример как по нормальному должен заполняться динамический массив. На С я очень давно не писал, не помню, но в php массивы именно так и заполняются! Всё логично и понятно. Если я добавляю элемент в массив (arr[] = x), то массив автоматически увеличивается, и элемент добавляется в конец массива. И не нужно самому растягивать его, и не нужно самому указывать индекс элемента. Здесь же нам приходится делать совершенно лишние движения:

разница очевидна...

на мой взгляд это, по меньшей мере, странно ))) 

Кто мешает воспользоваться ООП и реализовать похожий синтаксис?

#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:
Патамушта разработчики языка воспитаны на Сях и это сильно тормозит переход MQLа от хардкорной СИ-образности к попсовому PHP/JS-подобию. Это в плебейском PHP достаточно присвоить новое значение и массив сам подстроит свой размер, а MQL даёт прочувствовать насколько важная персона кодер. Так что берите лопату и наслаждайтесь причастностью к касте избранных профессионалов
На мой взгляд, не должен простой массив "подстраивать свой размер" без ведома программиста. Если необходимо такое поведение - должен писаться соответствующий класс. И потом - пользоваться без проблем "умным" массивом. А простые структуры, к которым изначально массив и относится - не должны иметь "прав самостоятельных решений"
 
Вам уже четверо сказали - возьмите лопату и напишите свой класс, раз он вам так нужен. ))
 
Сергей Таболин:

 "без ведома программиста" никак не получится. Именно программист и даёт команду "добавить элемент в конец массива" (arr[] = x). И массив никаких "прав самостоятельных решений" не имеет. Только выполняя команду программиста, он увеличивает свой размер, избавляя тем самым программиста от слежения за этим самым размером. )))

Как показывает мой опыт - если программист в массив, содержащий 10 элементов что-то записывает по индексу 20 - это с большой вероятностью означает, что он ошибся, и программа должна выдать ошибку, а не увеличивать размер массива, тем самым скрывая сомнительное действие.

Все эти "массивы, подстраивающие размер" несут гораздо больше проблем в связи с сокрытием потенциальных ошибок, чем удобства. Более того, и отсутствие необходимости слежения за размером массива - это также потенциально опасная практика, ведущая к трудно устранимым ошибкам.

Причина обращения: