Странное поведение оператора WHILE - страница 3

 
Нужно ли использовать WHILE, в то время как мы можем использовать FOR?
 

когда это происходит во время запуска и

когда это происходит во время остановки?

while (StringHighStatus == "False" && SwingHighShift <= SwingBarCount)
 
Это никогда не будет истинным (Операнд ==. - Форум MQL4)
if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift)
поэтому this никогда не будет выполнен
StringHighStatus="True";
что приводит к бесконечному циклу.
while(StringHighStatus=="False" || ...
  1. Если бы вы печатали свои переменные и записи до и внутри операторов if, вы бы это поняли.
  2. Не используйте строки или ints, когда вы имеете в виду boolean.
    string StringHighStatus = "False";
    while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          StringHighStatus = "True";
    
    bool String HighStatus = False;
    while (!String HighStatus || SwingHighShift <= SwingBarCount){
       if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == ...{
          String HighStatus = True;
    

 
WHRoeder:
Это никогда не будет истинным (Операнд ==. - Форум MQL4)
поэтому this никогда не будет выполнен
что приводит к бесконечному циклу.

Я тоже так думал, пока не протестировал, удивительно, но часть if(double == double) действительно работает, это заставляет меня задуматься, не обрабатывается ли сравнение двоек по-другому в новых билдах.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   for(int i=0; i<100; i++)
   {if(iFractals(NULL, 0, MODE_UPPER, i) == iHigh(NULL, 0, i) && iFractals(NULL, 0, MODE_UPPER, i) > Close[0])
    Print("Fractals conditions met on bar ",i);
  }} 

EURUSD,M15: Условия фракталов выполнены на баре 98
EURUSD,M15: Условия фракталов выполнены на баре 95
EURUSD,M15: Условия фракталов выполнены на баре 91
EURUSD,M15: Условия фракталов выполнены на баре 81
EURUSD,M15: Условия фракталов выполнены на баре 77
EURUSD,M15: Условия фракталов выполнены на баре 68
EURUSD,M15: Условия фракталов выполнены на баре 61
EURUSD,M15: Условия фракталов выполнены на баре 48
EURUSD,M15: Условия фракталов выполнены на баре 39
EURUSD,M15: Условия фракталов выполнены на баре 24
EURUSD,M15: Условия фракталов выполнены на баре 19
EURUSD,M15: Условия фракталов выполнены на баре 12
EURUSD,M15: Условия фракталов выполнены на баре 4

 
lord_hiro:

Спасибо GumRai за ваше терпение.

Возможно, я ошибаюсь и не могу понять логику...

Если первый IF превращает, как вы предлагаете, строку в "true" при, скажем, SwinghHighShift=10, то счетчик не увеличивается в этом цикле; после этого управление возвращается в WHILE: цикл должен закончиться в этой точке, потому что WHILE содержит логическое ИЛИ и одно из его условий выполнено.

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

Я думаю, что ваше соображение было бы верным при использовании оператора AND.

Следуя вашей интерпретации, я могу пропустить OR внутри WHILE; я могу просто поставить первое условие IF на строке: если переменная станет "истинной", то прерывание завершит WHILE, в противном случае счетчик будет идти дальше до своего максимума.

Код будет выглядеть так:


Но это все еще обходной путь и, к сожалению, он не объясняет (для меня), почему WHILE не справляется с OR.

Нет ничего плохого в WHILE или логическом ИЛИ, у вас есть два условия в вашем WHILE, и ОБА они должны быть нарушены, прежде чем WHILE сможет выйти.

Вот почему он застревает

  • Код входит в цикл WHILE. Оба условия изначально истинны.
  • Код проходит через цикл WHILE, увеличивая SwingHighShift++, пока не будет найден бар с фракталами, удовлетворяющими условиям IF.
  • Рано или поздно код вводит операторы IF, когда фракталы удовлетворяют условиям.
  • StringHighStatus изменяется на false, так что первое условие WHILE нарушается.
  • SwingHighShift++; НЕ увеличивается, потому что он находится в части ELSE оператора IF (условие IF было выполнено, поэтому ELSE игнорируется).
  • Второе условие WHILE все еще истинно, поэтому код циклически повторяет цикл STILL ON THE SAME BAR AS LAST TIME.
  • тот же фрактал снова выполняет условия IF, как и в прошлый раз.
  • Теперь код навсегда застрял в цикле на том баре с фракталом, который удовлетворяет условиям IF, потому что SwingHighShift++ в части ELSE не увеличивается, когда условия IF истинны.

Существует лишь небольшой шанс, что цикл while когда-либо выйдет из цикла, и это произойдет, когда условие IF не будет выполнено для всех 100 баров (SwingBarCount), так что второе условие WHILE будет нарушено раньше первого. Затем фракталы удовлетворяют условию IF и выполняется код, нарушающий условие первого WHILE (модификация StringHighStatus).

Вам нужно либо убрать SwingHighShift++; из ELSE и поместить его самостоятельно в цикл while после оператора IF, чтобы независимо от того, что происходит с условиями IF, он все равно увеличивался, и цикл мог перейти к следующему бару, либо использовать break после блока кода рисования объекта, чтобы выйти из цикла while, когда объект нарисован.

Вам также нужно дать объекту возможность создавать различные имена для себя, иначе он будет отрисован только один раз. (если вы не хотите, чтобы он был нарисован только один раз).

 
Я перечитал ваши сообщения в этой теме и понял, в чем причина вашего замешательства. Вы рассматриваете логику WHILE и OR в обратном порядке. OR - это не остановка WHILE. Это о том, чтобы продолжать его, когда одно из условий действительно... Это похоже на следующее: у вас есть два включенных светильника. Ваша инструкция гласит: "Пока горит свет 1 ИЛИ свет 2, продолжайте делать что-то". Очевидно, что перед завершением работы должны погаснуть обе лампочки, а не только одна из них.
 
SDC:

Я тоже так думал, пока не протестировал, удивительно, но if(double == double) часть этого работает, это заставляет меня задуматься, не обрабатывается ли сравнение двойников по-другому в новых билдах.

EURUSD,M15: Fractals conditions met on bar 98
EURUSD,M15: Fractals conditions met on bar 95
EURUSD,M15: Fractals conditions met on bar 91
EURUSD,M15: Fractals conditions met on bar 81
EURUSD,M15: Fractals conditions met on bar 77
EURUSD,M15: Fractals conditions met on bar 68
EURUSD,M15: Fractals conditions met on bar 61
EURUSD,M15: Fractals conditions met on bar 48
EURUSD,M15: Fractals conditions met on bar 39
EURUSD,M15: Fractals conditions met on bar 24
EURUSD,M15: Fractals conditions met on bar 19
EURUSD,M15: Fractals conditions met on bar 12
EURUSD,M15: Fractals conditions met on bar 4


Причина, по которой это работает, заключается в том, что код эффективно сравнивает одно и то же значение

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift) )

Фрактальный буфер будет либо иметь пустое значение, либо его значение будет взято из максимума соответствующего бара.

Код эффективно

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE && iHigh(NULL,0,SwingHighShift==iHigh(NULL,0,SwingHighShift) 

Я не вижу причин, по которым его нельзя заменить на

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
 
GumRai:

Я не вижу причин, по которым его нельзя заменить на

if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)!= EMPTY_VALUE)
Да, я думаю, что это лучший способ сделать это.
 
SDC:
Я перечитал ваши сообщения в этой теме и понял, где теперь возникает ваша путаница. Вы думаете о логике WHILE и OR в обратном порядке. OR - это не остановка WHILE. Это о том, чтобы продолжать его, когда одно из условий действительно... Это похоже на следующее: у вас есть два включенных светильника. Ваша инструкция гласит: "Пока горит свет 1 ИЛИ свет 2, продолжайте делать что-то". Очевидно, что перед завершением работы должны погаснуть обе лампочки, а не только одна из них.


Вот и все!

Как мне не стыдно... :-)

Более того, я не в первый раз использую WHILE, но я начал думать в обратном направлении и так и не вышел из СВОЕГО цикла :-/

Так что предложение deVries о замене || на && оказывается верным.

Из этой темы вытекает много других вещей, на которые следует обратить внимание, например, как работает IF( == ).

Спасибо всем за ваше терпение и время, которое вы потратили на то, чтобы я понял.

 

Я бы хотел сделать это таким образом, с помощью break, чтобы прервать цикл while, правильно ли это?

  int counter=0, MaxCount = 10000;
  while( true )
     {
      Print("Counter ", counter);
      counter++;
      if( counter == MaxCount ) break;
      }
   
Причина обращения: