预定义大量代替值
预定义大量代替值
为简化故障排除并获得MQL5程序运行的信息,有一种特殊的宏,是当时建立编辑的值。使用这些常量的最原始的方法是通过 Print() 函数输出值,如示例中所示。
| 常量 | 描述 |
|---|---|
| __CPU_ARCHITECTURE__ | 为之编译EX5文件的架构名称(命令集) |
| __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
*/