Fehler, Irrtümer, Fragen - Seite 1438

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

Und wenn das Problem mit der Array-Größe gelöst ist, sollten Sie trotzdem sehen, welche Werte pr_open und pr_close haben, wenn Sie sie zum ersten Mal aufrufen.


P./S.: Sie werden hier nicht initialisiert:

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

........
}

und man kann im Code nicht sehen, dass ihnen etwas zugewiesen ist.

Aber vielleicht ist ihre Initialisierung irgendwo darin versteckt:

.........

Codezeilen, die Sie versteckt haben.

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

Genau ))) Es gibt kein Problem mit ihnen.

Im Allgemeinen ist es ziemlich lästig, die Dimensionalität eines dynamischen Arrays ständig im Auge zu behalten... Sie müssen wissen, wie viel es wiegt. Was ist dann der Sinn? ....

Der Punkt ist, dass, wenn Sie nicht im Voraus wissen, wie viele Elemente in sie gesetzt werden, gibt es keine Notwendigkeit, ein statisches Array von einer garantierten größeren Größe (mit viel Spielraum, so dass es in jedem Fall passen) zu deklarieren und verschwenden Speicher. Wenn dem Array neue Daten hinzugefügt werden müssen, wird es einfach dynamisch vergrößert.
 
Сергей Таболин:

Im Prinzip ist dies verständlich. Das Einzige, was ich nicht verstehe, ist, warum dieses Feld nicht automatisch inkrementiert werden kann.

Warum konnte das nicht so gemacht werden? Das ist nicht meine Idee )))) Genau so habe ich versucht, ein dynamisches Array zu verwenden...

Außerdem muss ich den Index zusätzlich speichern... Nicht gut...

Wer sagt, dass man sie nicht dynamisch vergrößern kann?

Hier wird Ihnen geholfen

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

Wir sollten eine Hilfe für die Verwendung der Hilfe erstellen )))))))))))))))))))))

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

Im Prinzip ist dies verständlich. Das Einzige, was ich nicht verstehe, ist, warum dieses Feld nicht automatisch inkrementiert werden kann.

int arr[];

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

Warum konnte das nicht so gemacht werden? Das ist nicht meine Idee )))) Genau so habe ich versucht, ein dynamisches Array zu verwenden...

Außerdem muss ich den Index zusätzlich speichern... Nicht gut...

Ich verstehe nicht, was Sie mit diesem Code bezwecken wollten.

Hier haben wir ein kleines Beispiel skizziert, das zeigt, wozu dynamische Arrays da sind und wie man sie verwendet.

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

Ich verstehe nicht, warum dieses Feld nicht automatisch inkrementiert werden kann.

Weil die Sprachentwickler mit Syakh aufgewachsen sind und dies den Übergang von MQL von Hardcore-SI- zu Popsy-PHP/JS-ähnlich stark behindert. Im einfachen PHP wird einfach ein neuer Wert zugewiesen und das Array passt seine Größe automatisch an. MQL lässt den Programmierer seine Bedeutung spüren. Schnappen Sie sich also eine Schaufel und genießen Sie es, zu einer ausgewählten Kaste von Fachleuten zu gehören
 
Сергей Таболин:

Dies ist im Prinzip ein einfaches Beispiel dafür, wie ein dynamisches Array normalerweise gefüllt werden sollte. Ich habe schon lange nicht mehr in C geschrieben, ich kann mich nicht erinnern, aber so werden Arrays in php gefüllt! Alles ist logisch und verständlich. Wenn ich einem Array ein Element hinzufüge (arr[] = x), wird das Array automatisch erweitert, und das Element wird am Ende des Arrays hinzugefügt. Und wir müssen es nicht selbst strecken, und wir müssen den Index des Elements auch nicht selbst angeben. Aber hier müssen wir absolut unnötige Bewegungen machen:

der Unterschied ist offensichtlich...

Meiner Meinung nach ist das, gelinde gesagt, seltsam ))))

Nun, dann nehmen Sie eine Schaufel und schreiben Sie Ihre eigene Implementierung von dynamischen Arrays, die genau auf diese Weise funktionieren wird, was hält Sie davon ab? )) Obwohl, zu überladen [] für die Zuordnung MKL nicht zulassen wird, ist es nicht hardcore genug. ))
 
Сергей Таболин:

Dies ist im Prinzip ein einfaches Beispiel dafür, wie ein dynamisches Array normalerweise gefüllt werden sollte. Ich habe schon lange nicht mehr in C geschrieben, ich kann mich nicht erinnern, aber so werden Arrays in php gefüllt! Alles ist logisch und verständlich. Wenn ich einem Array ein Element hinzufüge (arr[] = x), wird das Array automatisch erweitert, und das Element wird am Ende des Arrays hinzugefügt. Und wir müssen es nicht selbst strecken, und wir müssen den Index des Elements auch nicht selbst angeben. Aber hier müssen wir absolut unnötige Bewegungen machen:

der Unterschied ist offensichtlich...

Ich finde das, gelinde gesagt, seltsam ))))

Wer hindert uns daran, OOP zu verwenden und eine ähnliche Syntax zu implementieren?

#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:
Da die Sprachentwickler mit Syakh aufgewachsen sind, wird der Übergang von MQL von einem Hardcore-SI- zu einem poppigen PHP/JS-ähnlichen System stark behindert. Im einfachen PHP wird einfach ein neuer Wert zugewiesen und das Array passt seine Größe automatisch an. MQL lässt den Programmierer seine Bedeutung spüren. Nehmen Sie also eine Schaufel und genießen Sie es, zu den wenigen Profis zu gehören.
Meiner Meinung nach sollte ein einfaches Array seine Größe nicht "anpassen", ohne dass der Programmierer es merkt. Wenn ein solches Verhalten erforderlich ist, muss eine entsprechende Klasse geschrieben werden. Und dann können Sie ohne Probleme ein "intelligentes" Array verwenden. Und einfache Strukturen, zu denen das Feld zunächst gehört, dürfen keine "unabhängigen Entscheidungsrechte" haben.
 
Vier Leute haben es dir schon gesagt: Nimm eine Schaufel und schreibe deine Klasse, weil du es so sehr willst. ))
 
Сергей Таболин:

"ohne das Wissen des Programmierers" funktioniert nicht. Es ist der Programmierer, der den Befehl "füge ein Element an das Ende des Arrays an" (arr[] = x) gibt. Und die Anordnung hat keine "unabhängigen Entscheidungsrechte". Erst durch die Ausführung des Befehls des Programmierers vergrößert es sich und entbindet den Programmierer davon, diese Größe im Auge zu behalten. )))

Wenn der Programmierer etwas in ein Array schreibt, das 10 Elemente mit dem Index 20 enthält, bedeutet das meiner Erfahrung nach höchstwahrscheinlich, dass er/sie einen Fehler gemacht hat, und das Programm sollte eine Fehlermeldung ausgeben, aber nicht die Größe des Arrays erhöhen und damit eine verdächtige Aktion verbergen.

All diese "Arrays, die die Größe anpassen" haben weit mehr Probleme mit dem Verbergen möglicher Fehler als mit der Bequemlichkeit. Darüber hinaus ist die Tatsache, dass die Array-Größe nicht verfolgt werden muss, eine potenziell gefährliche Praxis, die zu schwer zu behebenden Fehlern führt.