Semicolon после блока: непонятки

 
История такая. Скачал самый первый вариант ZigZag от Roshа на виаке. Прицепил на график. Похоже, действительно работает лучше, чем стандартный. Тебе, Rosh, большое спасибо за объяснение логики, которое я нашел там же, на первой страничке ветки.

Посмотрел на стиль структурирования кода индюкатора. В общем и целом он такой же, как и у стандартного, т.е. длиннющая start(), в логике которой без поллитра не разберешься. А разобраться очень надо, так как хочется его неслабо переделать.

Лично я предпочитаю функции не длиннее 15-20 строк, даже с комментами, - за редким исключением функций с очень простой, но по необходимости большой длиной кода, которые нет смысла структурировать. Пусть даже код немного проиграет в скорости из-за новых вызовов функций, зато будет нагляднее и легче для модификации.

В процессе реструктурирования столкнулся с такой проблемой. В "модуле" final cutting много операторов if с условием в блочных скобках и без вилки else. В твоем варианте, Rosh, такие усеченные конструкции завершаются точкой с запятой после блока, они даже помечены тобой специально:

   // final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtMapBuffer[shift];
      curhigh=ExtMapBuffer2[shift];

      //---
      if(curhigh!=0)
        {
         if(lasthigh>0)
           {
            if(lasthigh<curhigh) ExtMapBuffer2[lasthighpos]=0;
            else ExtMapBuffer2[shift]=0;
           };//я
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           };// я
         lastlow=-1;
        };//я

      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtMapBuffer[lastlowpos]=0;
            else ExtMapBuffer[shift]=0;
           };//z
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           };//z
         lasthigh=-1;
        };//
     }

Если убрать эти точки с запятыми, компиляция проходит нормально (правда, логика явно меняется). Если их оставить - компиляция обычно не проходит. Но не всегда. Т.е. компилятор иногда замечает их как ошибки, а иногда нет.

Где-то когда-то я видел обсуждение этой проблемы - кажись, для МТ3, - но так и не увидел внятного ответа. Кто-нибудь может дать ясный совет, что делать в такой ситуации? Можно, конечно, завершить усеченные конструкции "пустышками"...

P.S. Оказывается, я поторопился: твой индюк, Rosh, не компилится, если оставить твои "лишние" точки с запятой. ..
 

Раньше язык MQL-4 допускал (или требовал) точку с запятой после фигурной скобки. Потом это отменили, оставили только предупреждение в компиляторе. Компилироваться должен, сам только несколько дней назад компилировал.

 
Ну да, конечно: 0 ошибок, 6 предупреждений, компиляция идет.

Но интересно: 21.11.06 в 01:00 на часовках максимум индюкатора чуть выше, чем надо. В принципе на сигнал это не влияет, но где-то тут ошибка... или 23.11.06 07:00. Это, вероятно, влияние ExtDeviation?
 
В понедельник выложу версию,обработанную напильником.
 
Вот обещанная версия:
//+------------------------------------------------------------------+
//|                                                       Zigzag.mq4 |
//|                 Copyright © 2005-2007, MetaQuotes Software Corp. |
//|                                       https://www.metaquotes.net// |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net//"
 
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//---- indicator buffers
double ZigzagBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
int level=3; // recounting's depth 
bool downloadhistory;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ZigzagBuffer);
   SetIndexBuffer(1,HighMapBuffer);
   SetIndexBuffer(2,LowMapBuffer);
   SetIndexEmptyValue(0,0.0);
 
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int i, counted_bars = IndicatorCounted();
   int limit,counterZ,whatlookfor;
   int    shift, back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;
 
   if (counted_bars==0 && downloadhistory) // history was downloaded
     {
      ArrayInitialize(ZigzagBuffer,0.0);
      ArrayInitialize(HighMapBuffer,0.0);
      ArrayInitialize(LowMapBuffer,0.0);
     }
   if (counted_bars==0) 
     {
      limit=Bars-ExtDepth;
      downloadhistory=true;
     }
   if (counted_bars>0) 
     {
      while (counterZ<3 && i<100)
        {
         res=ZigzagBuffer[i];
         if (res!=0) counterZ++;
         i++;
        }
      i--;
      limit=i;
      if (LowMapBuffer[i]!=0) 
        {
         curlow=LowMapBuffer[i];
         whatlookfor=1;
        }
      else
        {
         curhigh=HighMapBuffer[i];
         whatlookfor=-1;
        }
      for (i=limit-1;i>=0;i--)  
        {
         ZigzagBuffer[i]=0.0;  
         LowMapBuffer[i]=0.0;
         HighMapBuffer[i]=0.0;
        }
     }
      
   for(shift=limit; shift>=0; shift--)
     {
      val=Low[iLowest(NULL,0,MODE_LOW,ExtDepth,shift)];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=LowMapBuffer[shift+back];
               if((res!=0)&&(res>val)) LowMapBuffer[shift+back]=0.0; 
              }
           }
        } 
      if (Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
      //--- high
      val=High[iHighest(NULL,0,MODE_HIGH,ExtDepth,shift)];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=HighMapBuffer[shift+back];
               if((res!=0)&&(res<val)) HighMapBuffer[shift+back]=0.0; 
              } 
           }
        }
      if (High[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
     }
 
   // final cutting 
   if (whatlookfor==0)
     {
      lastlow=0;
      lasthigh=0;  
     }
   else
     {
      lastlow=curlow;
      lasthigh=curhigh;
     }
   for (shift=limit;shift>=0;shift--)
     {
      res=0.0;
      switch(whatlookfor)
        {
         case 0: // look for  peak or lawn 
            if (lastlow==0 && lasthigh==0)
              {
               if (HighMapBuffer[shift]!=0)
                 {
                  lasthigh=High[shift];
                  lasthighpos=shift;
                  whatlookfor=-1;
                  ZigzagBuffer[shift]=lasthigh;
                  res=1;
                 }
               if (LowMapBuffer[shift]!=0)
                 {
                  lastlow=Low[shift];
                  lastlowpos=shift;
                  whatlookfor=1;
                  ZigzagBuffer[shift]=lastlow;
                  res=1;
                 }
              }
             break;  
         case 1: // look for peak
            if (LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lastlowpos]=0.0;
               lastlowpos=shift;
               lastlow=LowMapBuffer[shift];
               ZigzagBuffer[shift]=lastlow;
               res=1;
              }
            if (HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               lasthigh=HighMapBuffer[shift];
               lasthighpos=shift;
               ZigzagBuffer[shift]=lasthigh;
               whatlookfor=-1;
               res=1;
              }   
            break;               
         case -1: // look for lawn
            if (HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lasthighpos]=0.0;
               lasthighpos=shift;
               lasthigh=HighMapBuffer[shift];
               ZigzagBuffer[shift]=lasthigh;
              }
            if (LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               lastlow=LowMapBuffer[shift];
               lastlowpos=shift;
               ZigzagBuffer[shift]=lastlow;
               whatlookfor=1;
              }   
            break;               
         default: return; 
        }
     }
 
   return(0);
  }
//+------------------------------------------------------------------+
Она практически не отличается от версии билда 201 от 10.01.07
 
Спасибо, Rosh. Тут уже есть оптимизация вычислений с помощью IndicatorCounted(), очень интересно. Rosh, а что такое "напильник"?
 
Нужно скачать новый билд 201 от 12.01.07 и сравнить Zigzag из той поставки с этим. Будет видно, что вместо переработки алгоритма был использован метод грубой силы, то , что обычно называется "обработать напильником" в инструкциях :)
Причина обращения: