Macro de substitution (#define)

The preprocessor directives are used by the compiler to preprocess the source code before compiling it. The directive always begins with #, therefore the compiler prohibits using the symbol in names of variables, functions etc.

Each directive is described by a separate entry and is valid until the line break. You cannot use several directives in one entry. If the directive entry is too big, it can be broken into several lines using the '\' symbol. In this case, the next line is considered a continuation of the directive entry.

La directive #define peut être utilisée pour assigner des noms mnémoniques aux constantes. Il y a deux formes :

#define identifiant expression                   // forme sans paramètre
#define identifiant(par1,... par8) expression    // forme paramétrée

La directive #define substitue expression pour toutes les entrées trouvées de identifiant dans le texte source. L'identifiant n'est remplacé que s'il est sous forme séparée. L'identifiant n'est pas remplacé s'il fait partie d'un commentaire, d'une chaîne de caractères ou d'un autre identifiant plus long.

Les identifiants de constantes obéissent aux mêmes règles que les noms de variables. La valeur peut être de n'importe quel type :

#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 peut consister en différents éléments, tels que des mots-clés, des constantes, des expressions constantes et non-constantes. expression se termine avec la fin de la ligne et ne peut pas être transférée sur la ligne suivante.

Exemple :

#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);
  }
// Résultat
// 2 + 3*2 = 8
// (2 + 3)*2 = 10

 

Forme Paramétrique de #define

Avec la forme paramétrique, toutes les entrées trouvées de l'identifiant sont remplacées par l'expression en tenant compte des paramètres donnés. Par exemple :

 // exemple avec deux paramètres a et 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);
est équivalent à double c=((2+3)*(5-1));
*/
// Résultat
// c=20

Assurez-vous d'entourer les paramètres entre parenthèses lors de l'utilisation des paramètres dans expression, car ceci aidera à éviter des erreurs non évidentes qui sont difficiles à trouver. Si le code est réécrit sans les parenthèses, le résultat sera différent :

 // exemple avec deux paramètres a et 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);
est équivalent à double c=2+3*5-1;
*/
// Résultat
// c=16

Lors de l'utilisation de la forme paramétrique, un maximum de 8 paramètres est autorisé.

 // forme paramétrique correcte
#define LOG(text)  Print(__FILE__,"(",__LINE__,") :",text)   // un paramètre - 'text'
 
 // forme paramétrique incorrecte        
#define WRONG_DEF(p1, p2, p3, p4, p5, p6, p7, p8, p9)   p1+p2+p3+p4 // plus de 8 paramètres de p1 à p9

 

La directive #undef

La directive #undef annule la déclaration de la substitution de macro définie auparavant.

Exemple :

#define MACRO
 
void func1()
  {
#ifdef MACRO
   Print("MACRO est définie dans ",__FUNCTION__);   
#else
   Print("MACRO n'est pas définie dans ",__FUNCTION__);
#endif
  }
 
#undef MACRO
 
void func2()
  {
#ifdef MACRO
   Print("MACRO est définie dans ",__FUNCTION__);
#else
   Print("MACRO n'est pas définie dans ",__FUNCTION__);
#endif
  }
 
void OnStart()
  {
   func1();
   func2();
  }
 
/* Résultat :
MACRO est définie dans func1
MACRO n'est pas définie dans func2
*/

Voir aussi

Identifiants, Constantes Caractères