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

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

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

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 - это с большой вероятностью означает, что он ошибся, и программа должна выдать ошибку, а не увеличивать размер массива, тем самым скрывая сомнительное действие.

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

 
George Merts:

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

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

Мне кажется или вы не работали с языками о которых речь? Индекс добавляемому элементу указывать не нужно вообще, он присваивается автоматом и размерность массива увеличивается также. У программиста просто нет шанса ошибиться в индексе при этой операции

Можно реализовать похожее поведение классами, добавить связанные с ним функции pop, shift, unshift итд. И таскать телегу классов из кода в код, при том что в каждом коде из неё используются %10..20 функций. Похоже это на правильное решение? Пример правильного решения на моё имхо - добавление в функцию ObjectsDeleteAll возможности удалять по префиксу - это ещё микрон в сторону более высокоуровневого программирования - и у большинства кодеров улетела в корзину соотв самопальная функция. Увы, с массивами мы такого вряд ли дождёмсо..

 

И таскать телегу классов из кода в код, при том что в каждом коде из неё используются %10..20 функций.

О включаемых mqh файлах не слышали?
 

Не нужно писать классы "умных массивов", они уже есть в Стандартной библиотеке MetaQuotes, посмотрите семейство классов Arry