WHILE操作符的奇怪行为 - 页 3

 
我们可以用FOR,但是否需要用WHILE?
 

当这是而启动和

什么时候会出现这种情况而停止?

while (StringHighStatus == "False" && SwingHighShift <= SwingBarCount)
 
这永远不会是真的(==操作数。 - MQL4论坛
if(iFractals(NULL,0,MODE_UPPER,SwingHighShift)==iHigh(NULL,0,SwingHighShift)
因此,这一点永远不会被执行
StringHighStatus="True";
导致一个无限循环。
while(StringHighStatus=="False" || ...
  1. 如果你在if 语句之前和里面打印了你的变量和条目,你就会发现这个问题了。
  2. 当你指的是布尔值时,不要使用字符串或英特。
    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论坛
因此,这一点永远不会被执行
导致一个无限循环。

我也有同样的想法,直到我进行了测试,令人惊讶的是,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像你建议的那样,在SwinghHighShift=10时将字符串变成 "真",那么在这个循环中,计数不会增加;在那之后,控制回到WHILE:这个循环应该在这个点结束,因为WHILE包含一个逻辑OR,它的一个条件被满足。

反之,如果变量一直是假的,那么计数器应该达到它的最大值,你又有了退出条件。

我认为你的考虑对于一个AND操作符来说是正确的。

按照你的解释,我可以跳过WHILE中的OR;我可以只在字符串上设置第一个IF条件:如果变成 "true",那么break将结束WHILE,否则计数器将继续下去,直到它的最大值。

代码将转为。


但这仍然是一个变通的办法,而且,很遗憾,它并没有解释(对我来说)为什么WHILE不能处理OR的问题。

WHILE和逻辑OR都没有问题,你的WHILE中有两个条件,在WHILE退出之前,这两个条件都必须被打破。

这就是为什么它被卡住了

  • 代码进入了WHILE循环。两个条件在开始时都是真的。
  • 代码在WHILE循环中循环递增SwingHighShift++,直到找到一个满足IF条件的分形 柱。
  • 当分形满足条件时,代码迟早会进入IF运算。
  • StringHighStatus被改为false,所以第一个WHILE条件被打破。
  • SwingHighShift++;没有被递增,因为它在IF运算符的ELSE部分(IF条件被满足,所以ELSE被忽略了)。
  • 第二个WHILE条件仍然是真的,所以代码再次循环,仍然是在上次的相同的条上。
  • 同一个分形再次满足IF条件,就像上次一样。
  • 代码现在永远停留在那个符合IF条件的分形上循环,因为当IF条件为真时,ELSE部分的SwingHighShift++不会被递增。

只有一个很小的机会可以让while循环退出,那就是当IF条件在整个100个Bars(SwingBarCount)中都没有被满足,所以第二个WHILE条件在第一个之前就被打破了。然后,随后分形满足IF条件,打破第一个WHILE条件的代码(修改StringHighStatus)被执行。

你需要把SwingHighShift++;从ELSE中拿出来,并把它单独放在IF操作符之后的while循环中,这样不管IF条件发生什么,它仍然会递增,这样循环就可以进入下一个bar,或者在对象绘制代码块之后使用break,一旦对象被绘制,就可以脱离while。

你还需要给你的对象一个方法,为它自己创建不同的名字,否则它将只被绘制一次。(除非你只想让它被绘制一次)。

 
我回头看了看你在这个主题中的帖子,我知道你的困惑出现在哪里了。你把WHILE和OR的逻辑想反了。OR并不是要停止WHILE。它是关于在任何一个条件有效时保持它的运行......就像这样,你有两个灯打开了。你的指令是,当灯1或灯2亮时,继续做某事。很明显,在你退出之前,两个灯都必须关闭,而不是其中一个。
 
SDC:

我也是这么想的,直到我进行了测试,令人惊讶的是,if(double == double)的部分确实起作用了,这让我怀疑在新的构建中是否对双数的比较进行了不同的处理。

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条满足


之所以能成功,是因为代码有效地比较了相同的值

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;
      }