错误、漏洞、问题 - 页 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]);
 
Сергей Таболин:

我不明白为什么这个数组不能自动递增。

因为语言开发人员是在Syakh上长大的,而这严重阻碍了MQL从硬核的SI-like向Popsy PHP/JS-like的过渡。在普通的PHP中,人们只需分配一个新的值,数组就会自动调整其大小。 MQL使编码者感到其重要性。因此,拿起铲子,享受成为专业人员中的一员的乐趣吧
 
Сергей Таболин:

原则上,这是一个简单的例子,说明动态数组 通常应该如何填充。我已经很久没有用C语言写作了,我不记得了,但是在php中数组就是这样被填充的!一切都是合乎逻辑和可以理解的。如果我向一个数组添加一个元素(arr[] = x),数组会自动展开,这个元素会被添加到数组的末端。而且,我们不必自己把它拉出来,也不必自己指定元素的索引。但在这里,我们必须做出绝对不必要的动作。

区别很明显...

在我看来,这很奇怪,至少可以说))))。

好吧,那就拿着铲子写你自己的动态数组的实现,它将完全以这种方式工作,有什么理由阻止你?))虽然,要为MKL不允许的任务超载[],这还不够硬气。))
 
Сергей Таболин:

原则上,这是一个简单的例子,说明动态数组 通常应该如何填充。我已经很久没有用C语言写作了,我不记得了,但是在php中数组就是这样被填充的!一切都是合乎逻辑和可以理解的。如果我向一个数组添加一个元素(arr[] = x),数组会自动展开,这个元素会被添加到数组的末端。而且,我们不必自己把它拉出来,也不必自己指定元素的索引。但在这里,我们必须做出绝对不必要的动作。

区别很明显...

我觉得很奇怪,至少可以说))))

谁阻止我们使用OOP和实现类似的语法?

#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:
因为语言开发人员是在Syakh上长大的,这严重阻碍了MQL从硬核SI风格到类似PHP/JS的过渡。在普通的PHP中,人们只需分配一个新的值,数组就会自动调整其大小。 MQL使编码者感到其重要性。因此,拿着铲子,享受成为少数专业人员中的一员。
在我看来,一个简单的数组不应该在程序员不知道的情况下 "调整其大小"。如果这种行为是必要的,必须写一个相应的类。然后你就可以毫无问题地使用一个 "智能 "阵列。而最初属于阵列的简单结构,不得有 "独立决定权"。
 
有四个人已经告诉你了--既然你这么想,那就拿把铲子来写你的课吧。))
 
Сергей Таболин:

"在程序员不知情的情况下 "是不行的。是程序员发出了 "在数组的末尾添加一个元素 "的命令(arr[] = x)。而且该阵列没有 "独立的决定权"。只有通过执行程序员的命令,它才会增加其大小,从而使程序员不必再跟踪这个大小。)))

根据我的经验,如果程序员在一个包含10个项目、索引为20的数组中写了一些东西,这很可能意味着他/她犯了一个错误,程序应该产生一个错误,但不会增加数组的大小,从而隐藏一个可疑的行为。

所有这些 "调整大小的数组 "在隐藏潜在错误方面的问题远远多于它们的便利性。更重要的是,而且不用跟踪数组的大小也是一种潜在的危险做法,会导致难以修复的错误。