常量声明 (#define, #undef)

编译器使用预处理程序指令在编译之前对源代码进行预处理。这个指令通常以#开始,因此编译器禁止在变量,函数等名称中使用符号。

每个指令都由一个单独的条目描述,并且在换行符之前都是有效的。在一个条目中不能使用多个指令。如果指令条目太大,可以使用'\'符号将其分隔成若干行。 在这种情况下,下一行被认为是指令条目的延续。

#define直接用来指定常量助记名。有两种形式:

#define identifier expression                   // 无参数形式
#define identifier(par1,... par8) expression    // 参数形式

#define 直接代替 expression 为在源文件中找出更多的标识符目录。标识符仅代表自己时可被替换。如果标识符是注解一部分,字符串一部分或者其他标识符一部分,则不能代替。

常量标识符与变量名同样规则。值可以是多种类型:

#define ABC               100
#define PI                3.14
#define COMPANY_NAME      "MetaQuotes Software Corp."
...
void ShowCopyright()
  {
   Print("Copyright  2001-2009, ",COMPANY_NAME);
   Print("https://www.metaquotes.net");
  }

expression 由几种标记组成,例如关键字,常量,有常量无常量表达式。expression在直线末端结束,不可转到下一行。

示例:

#define TWO        2
#define THREE      3
#define INCOMPLETE TWO+THREE
#define COMPLETE  (TWO+THREE)
void OnStart()
  {
   Print("2 + 3*2 = ",INCOMPLETE*2);
   Print("(2 + 3)*2 = ",COMPLETE*2);
  }
// 结果
// 2 + 3*2 = 8
// (2 + 3)*2 = 10

 

参数形式 #define

通过参数形式,所有随后发现的标识符条目都将被考虑实际参数的表达式所取代。例如:

 // a和b两个参数的示例
#define A 2+3
#define B 5-1
#define MUL(a, b) ((a)*(b))
 
double c=MUL(A,B);
Print("c=",c);
/*
expression double c=MUL(A,B);
is equivalent to double c=((2+3)*(5-1));
*/
// 结果
// c=20

 

使用参数表达式时一定要在圆括号中附上参数,这将有助于避免不易发现的不明显的错误。如果我们不使用括号重写代码,结果将会有所不同:

 // a和b两个参数的示例
#define A 2+3
#define B 5-1
#define MUL(a, b) a*b
 
double c=MUL(A,B);
Print("c=",c);
/*
expression double c=MUL(A,B);
is equivalent to double c=2+3*5-1;
*/
// 结果
// c=16

使用参数形式时,最多允许8个参数。

 // 正确的参数形式
#define LOG(text)  Print(__FILE__,"(",__LINE__,") :",text)   // 一个参数 - 'text'
 
 // 不正确的参数形式       
#define WRONG_DEF(p1, p2, p3, p4, p5, p6, p7, p8, p9)   p1+p2+p3+p4 // 从p1到p9的超过8个参数

#undef 指令

定义之前,#undef 指令取消宏替换声明。

示例:

#define MACRO
 
void func1()
  {
#ifdef MACRO
   Print("MACRO is defined in ",__FUNCTION__);   
#else
   Print("MACRO is not defined in ",__FUNCTION__);
#endif
  }
 
#undef MACRO
 
void func2()
  {
#ifdef MACRO
   Print("MACRO is defined in ",__FUNCTION__);
#else
   Print("MACRO is not defined in ",__FUNCTION__);
#endif
  }
 
void OnStart()
  {
   func1();
   func2();
  }
 
/* Output:
 MACRO is defined in func1
 MACRO is not defined in func2
*/

另见

标识符字符常量