预定义大量代替值

为简化故障排除并获得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(exprPrint(#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 a1a2;
   print(a1.Method());
   print(a2.Method());                 // 该值没有更改
 
// 模板结构中的__COUNTER__
   B<intb1b2;
   B<doubleb3;
   print(b1.Method());
   print(b2.Method());                 // 该值没有更改
   print(b3.Method());                 // 该值已更改
 
// 模板函数结构中的__COUNTER__
   C c1c2;
   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
 
*/