预定义大量代替值

为简化故障排除并获得MQL5程序运行的信息,有一种特殊的宏,是当时建立编辑的值。使用这些常量的最原始的方法是通过 Print() 函数输出值,如示例中所示。

常量 描述
__DATE__ 文件编译日期,无时间(小时,分钟,秒等于0)
__DATETIME__ 文件编译日期和时间
__LINE__ 源代码中的字符串数量,宏放置的位置
__FILE__ 当前编辑文件的名称
__PATH__ 当前正在编译的文件的绝对路径
__FUNCTION__ 函数名称,宏主体位置
__FUNCSIG__ 宏所在的函数的签名。函数的完整描述记录可用于识别重载函数
__MQLBUILD__, __MQL5BUILD__ 编译器构造数量
__COUNTER__ 对于每个遇到的__COUNTER__声明,编译器都会将计数器值从0替换到N-1,这里N表示代码中的使用次数。重新编译源代码时,无需做任何更改,即可保证__COUNTER__顺序。 __COUNTER__值的计算方法如下:
  • 初始计数器值为0,
  • 每次使用计数器后,该值增加1,
  • 首先,编译器将所有宏和模板现场扩展为源代码,
  • 为每个模板函数专业化创建单独的代码,
  • 为每个模板类/结构专业化创建单独的代码,
  • 接下来,编译器按定义的顺序传递获取的源代码,并用当前计数器值替换每个检测到的__COUNTER__使用。
下面的示例显示了编译器如何处理源代码,并用顺序递增的值替换它遇到的__COUNTER__的所有实例。
__RANDOM__ 编译器为每个__RANDOM__声明插入一个随机ulong值。

示例:

#property copyright "Copyright © 2009, MetaQuotes Software Corp."

#property link      "https://www.metaquotes.net"

//+------------------------------------------------------------------+

//| 专家初始化函数                                                     |

//+------------------------------------------------------------------+

void OnInit()

  {

//--- EA交易初始化输出信息示例

   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);

//--- 设置定时器事件间的间隔

   EventSetTimer(5);

//---

  }

//+------------------------------------------------------------------+

//| 专家无法初始化函数                                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//--- EA交易无法初始化输出信息示例

   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);

//---

  }

//+------------------------------------------------------------------+

//| 专家订单号函数                                                     |

//+------------------------------------------------------------------+

void OnTick()

  {

//--- 订单收据输出信息

   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);

   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);

   test1(__FUNCTION__);

   test2();

//---

  }

//+------------------------------------------------------------------+

//| test1                                                            |

//+------------------------------------------------------------------+

void test1(string par)

  {

//--- 函数内部信息输出

   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__," par=",par);

  }

//+------------------------------------------------------------------+

//| test2                                                            |

//+------------------------------------------------------------------+

void test2()

  {

//--- 函数内部信息输出

   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);

  }

//+------------------------------------------------------------------+

//| OnTimer event handler                                            |

//+------------------------------------------------------------------+

void OnTimer()

  {

//---

   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);

   test1(__FUNCTION__);

  }

了解如何使用 __COUNTER__宏的示例

//--- 创建一个宏,以便在日志中快速显示表达式及其值

#define print(expr) Print(#expr,"=",expr)



//--- 通过预定义的__COUNTER__宏定义MACRO_COUNTER自定义宏

#define MACRO_COUNTER __COUNTER__



//--- 使用__COUNTER__宏设置变量的输入值

input int InpVariable = __COUNTER__;



//--- 定义函数之前,使用__COUNTER__宏设置全局变量的值

int ExtVariable = __COUNTER__;



//+------------------------------------------------------------------+

//| 函数返回__COUNTER__值                                             |

//+------------------------------------------------------------------+

int GlobalFunc(void)

  {

   return(__COUNTER__);

  }

//+------------------------------------------------------------------+

//| 模板函数返回__COUNTER__值                                          |

//+------------------------------------------------------------------+

template<typename T>

int GlobalTemplateFunc(void)

  {

   return(__COUNTER__);

  }

//+------------------------------------------------------------------+

//| 方法返回__COUNTER__的结构                                          |

//+------------------------------------------------------------------+

struct A

  {

   int               dummy;  // not used



   int               Method(void)

     {

      return(__COUNTER__);

     }

  };

//+------------------------------------------------------------------+

//| 方法返回__COUNTER__的模板结构                                       |

//+------------------------------------------------------------------+

template<typename T>

struct B

  {

   int               dummy;  // not used



   int               Method(void)

     {

      return(__COUNTER__);

     }

  };

//+------------------------------------------------------------------+

//| 模板方法返回__COUNTER__的结构                                       |

//+------------------------------------------------------------------+

struct C

  {

   int               dummy;  // not used



   template<typename T>

   int               Method(void)

     {

      return(__COUNTER__);

     }

  };

//+------------------------------------------------------------------+

//| 函数#2,返回__COUNTER__值                                          |

//+------------------------------------------------------------------+

int GlobalFunc2(void)

  {

   return(__COUNTER__);

  }

//+------------------------------------------------------------------+

//| 脚本程序起始函数                                                    |

//+------------------------------------------------------------------+

void OnStart(void)

  {

// 宏和变量中的__COUNTER__

   print(MACRO_COUNTER);

   print(InpVariable);

   print(ExtVariable);



//--- 函数中的__COUNTER__

   print(GlobalFunc());

   print(GlobalFunc());                // 该值没有更改

   print(GlobalTemplateFunc<int>());

   print(GlobalTemplateFunc<int>());   // the value is not changed

   print(GlobalTemplateFunc<double>());// 该值已更改

   print(GlobalFunc2());

   print(GlobalFunc2());               // 该值没有更改



// 结构中的__COUNTER__

   A a1, a2;

   print(a1.Method());

   print(a2.Method());                 // 该值没有更改



// 模板结构中的__COUNTER__

   B<int> b1, b2;

   B<double> b3;

   print(b1.Method());

   print(b2.Method());                 // 该值没有更改

   print(b3.Method());                 // 该值已更改



// 模板函数结构中的__COUNTER__

   C c1, c2;

   print(c1.Method<int>());

   print(c1.Method<double>());         // 该值已更改

   print(c2.Method<int>());            // 与第一个c1.Method<int>()调用中的相同值



//--- 让我们再看一下宏和全局变量中的__COUNTER__

   print(MACRO_COUNTER);  //该值已更改

   print(ExtGlobal2);

  }

//--- 定义函数之后,使用__COUNTER__宏设置全局变量的值

int ExtGlobal2 = __COUNTER__;

//+------------------------------------------------------------------+



/* Result

   __COUNTER__=3

   InpVariable=0

   ExtVariable=1

   GlobalFunc()=5

   GlobalFunc()=5

   GlobalTemplateFunc<int>()=8

   GlobalTemplateFunc<int>()=8

   GlobalTemplateFunc<double>()=9

   GlobalFunc2()=7

   GlobalFunc2()=7

   a1.Method()=6

   a2.Method()=6

   b1.Method()=10

   b2.Method()=10

   b3.Method()=11

   c1.Method<int>()=12

   c1.Method<double>()=13

   c2.Method<int>()=12

   __COUNTER__=4

   ExtGlobal2=2



*/