Erreurs, bugs, questions - page 1438

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

Exactement ;))) Il n'y a pas de problème avec eux.

D'une manière générale, il n'est pas très pratique de garder en permanence la trace de la dimension d'un tableau dynamique... Vous devez savoir combien il pèse. A quoi ça sert, alors ? ....

Le fait est que si vous ne savez pas à l'avance combien d'éléments seront placés dans le tableau, il n'est pas nécessaire de déclarer un tableau statique d'une taille plus grande garantie (avec beaucoup de marge, pour qu'il tienne dans tous les cas) et de gaspiller de la mémoire. Simplement, à mesure que de nouvelles données doivent être ajoutées au tableau, vous augmentez dynamiquement sa taille.
 
Сергей Таболин:

En principe, cela est compréhensible. La seule chose que je ne comprends pas est pourquoi ce tableau ne peut pas être incrémenté automatiquement.

Pourquoi ça ne pourrait pas être fait de cette façon ? Ce n'est pas mon idée )))) C'est exactement comme ça que j'ai essayé d'utiliser un tableau dynamique...

En plus, je dois sauvegarder l'index... Pas bon...

Qui a dit que vous ne pouviez pas l'agrandir dynamiquement ?

Nous sommes là pour vous aider

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

Nous devrions faire une aide sur la façon d'utiliser l'aide ))))))))))))))))))))).

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

En principe, cela est compréhensible. Ce qui n'est pas clair, c'est pourquoi ce tableau ne peut pas être incrémenté automatiquement.

int arr[];

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

Pourquoi ça ne pourrait pas être fait de cette façon ? Ce n'est pas mon idée )))) C'est exactement comme ça que j'ai essayé d'utiliser un tableau dynamique...

En plus, je dois sauvegarder l'index... Pas bon...

Je ne comprends pas ce que vous avez essayé de faire dans ce code.

Ici, je vous ai esquissé un petit exemple montrant à quoi servent les tableaux dynamiques et comment les utiliser.

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

Je ne comprends pas pourquoi ce tableau ne peut pas être incrémenté automatiquement.

Parce que les développeurs de langage ont été élevés sur Syakh, et que cela entrave gravement la transition de MQL du style SI pur et dur au style PHP/JS. Dans le PHP plébéien, il suffit d'assigner une nouvelle valeur et le tableau ajuste sa taille automatiquement. MQL fait sentir au codeur son importance. Alors prenez une pelle et appréciez de faire partie d'une caste de professionnels triés sur le volet.
 
Сергей Таболин:

Il s'agit, en principe, d'un exemple simple de la manière dont un tableau dynamique doit normalement être rempli. Je n'ai pas écrit en C depuis longtemps, je ne me souviens pas, mais c'est comme ça que les tableaux sont remplis en php ! Tout est logique et compréhensible. Si j'ajoute un élément à un tableau (arr[] = x), le tableau est automatiquement étendu, et l'élément est ajouté à la fin du tableau. Et nous n'avons pas besoin de l'étirer nous-mêmes, ni de spécifier l'index de l'élément nous-mêmes. Mais ici, nous devons faire des mouvements absolument inutiles :

la différence est évidente...

À mon avis, c'est étrange, pour ne pas dire plus. ))))

Eh bien, prenez une pelle et écrivez votre propre implémentation des tableaux dynamiques, qui fonctionnera exactement de cette façon, qu'est-ce qui vous en empêche ? )) Bien que, pour surcharger [] pour une affectation que MKL ne permet pas, ce n'est pas assez hardcore. ))
 
Сергей Таболин:

Il s'agit, en principe, d'un exemple simple de la manière dont un tableau dynamique doit normalement être rempli. Je n'ai pas écrit en C depuis longtemps, je ne me souviens pas, mais c'est comme ça que les tableaux sont remplis en php ! Tout est logique et compréhensible. Si j'ajoute un élément à un tableau (arr[] = x), le tableau est automatiquement étendu, et l'élément est ajouté à la fin du tableau. Et nous n'avons pas besoin de l'étirer nous-mêmes, ni de spécifier l'index de l'élément nous-mêmes. Mais ici, nous devons faire des mouvements absolument inutiles :

la différence est évidente...

Je trouve cela étrange, c'est le moins que l'on puisse dire )))).

Qui nous empêche d'utiliser la POO et d'implémenter une syntaxe similaire ?

#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:
Étant donné que les développeurs de langage ont été élevés sur Syakh, cela entrave sérieusement la transition de MQL du hardcore SI-like au poppy PHP/JS-like. Dans le PHP plébéien, il suffit d'assigner une nouvelle valeur et le tableau ajuste sa taille automatiquement. MQL fait sentir au codeur son importance. Alors, prenez une pelle et profitez d'être un membre des quelques professionnels sélectionnés.
À mon avis, un simple tableau ne devrait pas "ajuster sa taille" sans que le programmeur en soit conscient. Si un tel comportement est nécessaire, une classe correspondante doit être écrite. Et vous pouvez alors utiliser un tableau "intelligent" sans aucun problème. Et les structures simples, auxquelles le tableau appartient initialement, ne doivent pas avoir de "droits de décision indépendants".
 
Quatre personnes vous l'ont déjà dit : prenez une pelle et écrivez votre cours, puisque vous en avez tant besoin. ))
 
Сергей Таболин:

"à l'insu du programmeur" ne fonctionne pas. C'est le programmeur qui donne la commande "ajouter un élément à la fin du tableau" (arr[] = x). Et le tableau n'a pas de "droits de décision indépendants". Ce n'est qu'en exécutant la commande du programmeur qu'il augmente sa taille, dispensant ainsi le programmeur de surveiller cette même taille. )))

Comme le montre mon expérience, si le programmeur écrit quelque chose dans un tableau contenant 10 éléments avec l'index 20, cela signifie très probablement qu'il/elle a fait une erreur, et le programme devrait générer une erreur, mais ne pas augmenter la taille du tableau, cachant ainsi une action suspecte.

Tous ces "tableaux qui modifient la taille" ont beaucoup plus de problèmes pour cacher des erreurs potentielles que pour être pratiques. De plus, le fait de ne pas avoir à garder la trace de la taille du tableau est également une pratique potentiellement dangereuse, qui conduit à des bogues difficiles à corriger.

 
George Merts:

Comme le montre mon expérience, si le programmeur écrit quelque chose dans un tableau contenant 10 éléments avec l'index 20, cela signifie très probablement qu'il/elle a fait une erreur et que le programme devrait générer une erreur au lieu d'augmenter la taille du tableau, cachant ainsi une action douteuse.

Tous ces "tableaux ajustant la taille" sont beaucoup plus gênants en termes de dissimulation d'erreurs potentielles que pratiques. De plus, le fait de ne pas avoir à tenir compte de la taille d'un tableau est également une pratique potentiellement dangereuse, qui peut entraîner des bogues difficiles à corriger.

C'est moi, ou vous n'avez pas travaillé avec les langues en question ? Il n'est pas nécessaire de spécifier un index à ajouter : il est attribué automatiquement et la taille du tableau est également augmentée. Le programmeur n'a tout simplement pas la possibilité de faire une erreur avec l'index pendant cette opération.

Vous pouvez mettre en œuvre un comportement similaire avec des classes, ajouter les fonctions connexes pop, shift, unshift, etc. Et faire glisser un wagon de classes d'un code à l'autre, avec chaque code utilisant %10...20 fonctions de celui-ci. Cela vous semble-t-il une bonne solution ? Un exemple de bonne solution, à mon avis, est l'ajout à la fonction ObjectsDeleteAll de la possibilité de supprimer par préfixe - c'est un autre micron vers une programmation de plus haut niveau - et la plupart des codeurs se sont jetés sur la corbeille, donc sur la fonction qu'ils ont créée eux-mêmes. Hélas, on ne verra guère cela avec les tableaux...