mql5语言的特点、微妙之处以及技巧 - 页 152

 
Slava:

有吗?你确定它在那里吗?它在哪条路上?

我怎样才能重现它呢?

将脚本放在导航仪的收藏夹中

void OnStart() {}


编译错误的版本。

void OnStart() {} 123


重新启动终端,并尝试从收藏夹编辑脚本。

 
Vladimir Simakov:

开发人员。需要作出解释。相信哪个?文档还是实施?到目前为止,出现了未定义的行为。

@fxsaber,我不建议你在官方解释之前使用它,也许他们会修复它。

文件积压了,让我们来解决。

我不建议用表达式来初始化静态变量,如果可能的话,使用常量。

因为当你使用非常数表达式时,编译器会生成以下代码

//--- исходная функция
int func(int value)
  {
   static int myStaticVar=value;    
   
   myStaticVar += value;
   return(myStaticVar);
  }

//--- то, что будет сгенерировано 
bool __Implicit_myStaticVar_initialized=false;
int  __Implicit_myStaticVar=0;

//--- исходная функция
int func(int value)
  {
   if(!__Implicit_myStaticVar_initialized)
     {
      __Implicit_myStaticVar_initialized=true;
      __Implicit_myStaticVar=value;
     }

   __Implicit_myStaticVar += value;
   return(__Implicit_myStaticVar);
  }


有一个开销,每次调用都会检查__Implicit_myStaticVar_initialized标志。

对于常数情况,你将得到以下代码

//--- исходная функция
int func(int value)
  {
   static int myStaticVar=10;

   myStaticVar += value;
   return(myStaticVar);
  }

//--- то, что будет сгенерировано 
int  __Implicit_myStaticVar=10;

int func(int value)
  {
   __Implicit_myStaticVar += value;
   return(__Implicit_myStaticVar);
  }

没有开销。

 
Ilyas:

谢谢你,现在我明白了关于开销的问题。

 
你可以很容易地把非正常化的价格值写成自定义字符。下面是一个简单的检查。
bool IsNorm( const double Price )
{
  return(NormalizeDouble(Price, _Digits) == Price);
}

#define  TOSTRING(A) #A + " = " + DoubleToString(A, 16) + " "
#define  PRINT(A) Print(TOSTRING(A) + TOSTRING(NormalizeDouble(A, _Digits)))
#define  ISNORM(A) if (!IsNorm(A)) PRINT(A);

void OnTick()
{
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
  {
    ISNORM(Tick.bid)
    ISNORM(Tick.ask)
    ISNORM(Tick.last)
  }
}


结果

2019.12.11 06:46:56.458 2019.10.09 23:59:00   Tick.last = 1.8151900000000002 NormalizeDouble(Tick.last,_Digits) = 1.8151900000000000 
2019.12.11 06:46:56.458 2019.10.09 23:59:11   Tick.bid = 1.8151100000000003 NormalizeDouble(Tick.bid,_Digits) = 1.8151100000000001 
2019.12.11 06:46:56.458 2019.10.09 23:59:11   Tick.ask = 1.8153800000000003 NormalizeDouble(Tick.ask,_Digits) = 1.8153800000000001 
2019.12.11 06:46:56.458 2019.10.09 23:59:17   Tick.bid = 1.8151200000000002 NormalizeDouble(Tick.bid,_Digits) = 1.8151199999999999 
2019.12.11 06:46:56.458 2019.10.09 23:59:17   Tick.ask = 1.8153800000000003 NormalizeDouble(Tick.ask,_Digits) = 1.8153800000000001 
 
与本主题无关的评论已被移至"来自MQL5 MT5 MetaTrader 5初学者的问题"。
 
RickD:
...这个问题是不同的。也许MQL5中存在一个错误,我们需要处理它,但把它推迟到新手的话题中并不能帮助我们尽快解决这个问题。

请阅读该主题的标题。

 
Artyom Trishkin:

请阅读该主题的标题。

而你在哪里看到了矛盾?所描述的情况可能是语言的一个特点,也可能是一个错误。这就是你想了解的情况。

 
RickD:

而你在哪里看到了矛盾?所描述的情况可能是语言的一个特点,也可能是一个错误。这就是你想了解的情况。

首先,它被发现是一个错误或一个特殊性 - 然后它被准确地张贴出来,并且完全是一个特殊性。该主题只涉及功能。

 

@Ilyas@Slava@Renat Fatkhullin

mql支持函数的无记录关键字

__inline
__forceinline

使用它们是否合理?
如果是的话,编译器何时接受它们?

 

在ArrayReverse的帮助下。

ArraySetAsSeries()函数并没有实际移动数组中的元素,只是将索引方向向后扭转,以安排对元素的访问,就像在一个时间序列中一样。 ArrayReverse()函数在物理上移动数组项,使数组被 "反转"。

但这个代码证明了相反的情况。

  MqlRates rt[];
  CopyRates(Symbol(), 0, 0, 5, rt);
  ArraySetAsSeries(rt, true);
  ArrayResize(rt, 6); // добавляет элемент в конец массива
  //ArraySetAsSeries(rt, true);
  for (int x = 0; x < ArraySize(rt); x++) {
      Print(rt[x].time);
  }
  Print("=================");
(EURUSD,H1)     2019.12.13 02:00:00
(EURUSD,H1)     2019.12.13 01:00:00
(EURUSD,H1)     2019.12.13 00:00:00
(EURUSD,H1)     2019.12.12 23:00:00
(EURUSD,H1)     2019.12.12 22:00:00
(EURUSD,H1)     1970.01.01 00:00:00 - последний элемент
(EURUSD,H1)     =================
  MqlRates rt[];
  CopyRates(Symbol(), 0, 0, 5, rt);
  //ArraySetAsSeries(rt, true);
  ArrayResize(rt, 6); // добавляет элемент в конец массива
  ArraySetAsSeries(rt, true);
  for (int x = 0; x < ArraySize(rt); x++) {
      Print(rt[x].time);
  }
  Print("=================");
(EURUSD,H1)     1970.01.01 00:09:19 - последний элемент
(EURUSD,H1)     2019.12.13 02:00:00
(EURUSD,H1)     2019.12.13 01:00:00
(EURUSD,H1)     2019.12.13 00:00:00
(EURUSD,H1)     2019.12.12 23:00:00
(EURUSD,H1)     2019.12.12 22:00:00
(EURUSD,H1)     =================