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

 
x572intraday #:

 Багом называть не рискну. Поэтому просто скажу, что заметил одну особенность оператора if. Прозреваю, это может относиться и к другим ЯПам.

Если a окажется true, то проверка перейдёт к Array[over_index] и тут-то терминал начнёт дико бомбить по части 'array out of range', что совершенно справедливо. Если же a окажется false, до проверки условия истинности Array[over_index], а значит, и избыточности индекса дело не дойдёт, if проскочит дальше, а кодер так и не узнает, что у него в программе гуляет массив с несуществующим индексом... точнее существующим, но избыточным.

 Может, это надо пофиксить, чтобы проверка на предмет  'array out of range' происходила в if до самого конца и выдавалось бы такое же сообщение? Или это сильно уронит скорость работы оператора?

Если изменить поведение, то нормально написанные программы просто "упадут", а те которые не написаны, будет сложно написать.

Почитайте, там есть некоторое описание

 
x572intraday #:

Багом называть не рискну.

это нормальное поведение везде. если вам надо чтобы аргумент вычислялся всегда, вычисляйте его перед if-ом

 
Alexey Viktorov #:

В вашем случае это не так поскольку должны быть выполнены оба условия. А вот если поставить такое

то, да. При выполненном условии «а» второе условие проверяться не будет. За это боролись много лет, а вы теперь предлагаете вернуться в прошлый век…

Проверьте

// +--------
int start()
{
 if(false && Test()) { 
  Print("if Yes"); // Это никогда не напечатает
 }
}

// +--------
bool Test() {
 Print("Test"); // Это тоже, к ней не дошла очередь
 return(true);
}
 
Alexey Viktorov #:

В вашем случае это не так поскольку должны быть выполнены оба условия. А вот если поставить такое

то, да. При выполненном условии «а» второе условие проверяться не будет. За это боролись много лет, а вы теперь предлагаете вернуться в прошлый век…

 Как ни странно, но с a=true не только при ||, но и при && проверка остального не происходит. Иначе как объяснить вот это (смысл в работе индикатора искать не стоит, тут речь именно о коде):

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_ARROW
#property indicator_color1  Gray
#property indicator_label1  "Fractal Up"
//--- indicator buffers
double ExtUpperBuffer[];
//--- 10 pixels upper from high price
int    ExtArrowShift=-10;

void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtUpperBuffer,INDICATOR_DATA);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_ARROW,217);
//--- arrow shifts when drawing
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,ExtArrowShift);
//--- sets drawing line empty value--
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(rates_total<5)
      return(0);

   int start;
//--- clean up arrays
   if(prev_calculated<7)
     {
      start=2;
      ArrayInitialize(ExtUpperBuffer,EMPTY_VALUE);
     }
   else
      start=rates_total-5;

   for(int i=start; i<rates_total-3 && !IsStopped(); i++)
     {
      //--- Upper Fractal
      if(high[i]>high[i+1] && high[i]>high[i+2] && high[i]>high[i+3] && high[i]>high[i+4])
         ExtUpperBuffer[i]=high[i];
      else
         ExtUpperBuffer[i]=EMPTY_VALUE;
     }

   return(rates_total);
  }

Терминал молчит. Но стоит поменять

if(high[i]>high[i+1] && high[i]>high[i+2] && high[i]>high[i+3] && high[i]>high[i+4])

на

if(high[i]>high[i+4] && high[i]>high[i+2] && high[i]>high[i+3] && high[i]>high[i+1])

как появляется пресловутое сообщение  'array out of range', потому как if сразу же натыкается на массив с избыточным индексом, в отличие от первого варианта.

 
x572intraday #:

 Багом называть не рискну. Поэтому просто скажу, что заметил одну особенность оператора if. Прозреваю, это может относиться и к другим ЯПам.

Если a окажется true, то проверка перейдёт к Array[over_index] и тут-то терминал начнёт дико бомбить по части 'array out of range', что совершенно справедливо. Если же a окажется false, до проверки условия истинности Array[over_index], а значит, и избыточности индекса дело не дойдёт, if проскочит дальше, а кодер так и не узнает, что у него в программе гуляет массив с несуществующим индексом... точнее существующим, но избыточным.

 Может, это надо пофиксить, чтобы проверка на предмет  'array out of range' происходила в if до самого конца и выдавалось бы такое же сообщение? Или это сильно уронит скорость работы оператора?


На каком языке отличается синтаксис?  "Синтаксис в буквальном переводе означает не только составление, но и упорядочивание..".

Если вы хотите проверить, есть ли 'array out of range' , измените порядок.

if(Array[over_index]>val && a) {...}
 
Lilita Bogachkova #:

На каком языке отличается синтаксис?  "Синтаксис в буквальном переводе означает не только составление, но и упорядочивание..".

Если вы хотите проверить, есть ли 'array out of range' , измените порядок.

Порядок желателен по мере необходимости проверок.

К примеру, если "a" изменяется чаще, то её лучше ставить первым аргументом.

 
Vitaly Muzichenko #:

Порядок желателен по мере необходимости проверок.

К примеру, если "a" изменяется чаще, то её лучше ставить первым аргументом.

Нет, от первого зависят основные условия, от остальных - просто дополнительные.

Например, неактуально проверять час текущего рабочего времени, если рабочее время еще не началось.
 

 Вообще, я случайно наткнулся на эту особенность. А хотел совсем другого...

if(high[i]>high[i+1] && high[i]>high[i+2] && high[i]>high[i+3] && ... && high[i]>high[i+n])

либо

if(high[i]>high[i+1])
   if(high[i]>high[i+2])
      if(high[i]>high[i+3])
         if(...)
            if(high[i]>high[i+n])

Тягомотина в том, что n может быть достаточно велико, поэтому эту длинную цепочку условий захотелось завернуть в компактный for. Попробовал так:

for(int i=start; i<rates_total-3 && !IsStopped(); i++)
{
   bool h_plus=true; //false?
   for(int increment=1; increment<=n; increment++)
      h_plus&=high[i]>high[i+increment];
   if(h_plus) {...}
   ...
}

но вышла какая-то шляпа. Ну хотя бы потому, что h_plus при таком алгоритме будет вынужден принять всю сумму проверяемых условий, включая условие с проверкой массива с избыточным индексом, до чего дело не доходило в первом развёрнутом if, без for который. Ну и прочие варнинги картину портят.

 Стоит ли такое вообще хотеть? Возможно ли такое за-for'ить?

 
Lilita Bogachkova #:

На каком языке отличается синтаксис?  "Синтаксис в буквальном переводе означает не только составление, но и упорядочивание..".

Если вы хотите проверить, есть ли 'array out of range' , измените порядок.

 Не всегда заранее известно, что ставить впереди, а что после.

 
Lilita Bogachkova #:

Нет, от первого зависят основные условия, от остальных - просто дополнительные.

Например, неактуально проверять час текущего рабочего времени, если рабочее время еще не началось.

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

Верно?