Dichiarazione di costanti (#define, #undef)

Le direttive del preprocessore sono usate dal compilatore per pre-elaborare il codice sorgente prima di compilarlo. La direttiva inizia sempre con #, quindi il compilatore vieta l'utilizzo del simbolo nei nomi di variabili, funzioni, ecc.

Ogni direttiva è descritta da una voce separata ed è valida fino all'interruzione di riga. Non è possibile utilizzare più direttive in un'unica voce. Se la voce direttiva è troppo grande, può essere suddivisa in più righe usando il simbolo '\'. In questo caso, la riga successiva è considerata una continuazione della voce direttiva.

La direttiva #define può essere utilizzata per assegnare i nomi alle costanti mnemoniche. Ci sono due forme:

#define definizione dell'espressione // parametro-forma libera
#define identificatore(par1,... par8) espressione    // forma parametrica

La direttiva #define sostitutisce l'espressione per tutte le altre voci trovate di identificatore nel testo di partenza. L'identificatore è sostituito solo se è un token separato. L' identificatore non è sostituito se è parte di un commento, parte di una stringa, o parte di un altro identificatore più.

L'identificatore costante è governato dalle stesse regole dei nomi delle variabili. Il valore può essere di qualsiasi tipo:

#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 può essere costituito da vari token, quali parole chiave, costanti, espressioni costanti e non-costanti. expression termina con l'estremità della linea e non può essere trasferito alla linea successiva.

Esempio:

#define DUE        2
#define TRE      3
#define INCOMPLETO DUE+TRE
#define COMPLETO  (DUE+TRE)
voidOnStart()
  {
   Print("2 + 3*2 = ",INCOMPLETO*2);
   Print("(2 + 3)*2 = ",COMPLETO*2);
  }
// Risultato
// 2 + 3*2 = 8
// (2 + 3)*2 = 10

 

Forma parametrica #define

With the parametric form, all the subsequent found entries of identifier will be replaced by expression taking into account the actual parameters. Ad esempio:

 // esempio con due paremetri, a e b
#define A 2+3
#define B 5-1
#define MUL(a, b) ((a)*(b))
 
double c=MUL(A,B);
Print("c=",c);
/*
l'esprezzione double c=MUL(A,B);
è equivalente a double c=((2+3)*(5-1));
*/
// Risultato
// c=20

Accertarsi di racchiudere i parametri tra parentesi quando si utilizzano i parametri di espressione, in modo da evitare errori non-ovvi che sono difficili da trovare. Se si riscrive il codice senza usare le parentesi, il risultato sarà diverso:

 // esempio con due paremetri, a e b
#define A 2+3
#define B 5-1
#define MUL(a, b) a*b
 
double c=MUL(A,B);
Print("c=",c);
/*
l'esprezzione double c=MUL(A,B);
è equivalente a double c=2+3*5-1;
*/
// Risultato
// c=16

Quando si utilizza la forma parametrica, un massimo di 8 parametri sono ammessi.

 // forma parametrica corretta
#define LOG(text)  Print(__FILE__,"(",__LINE__,") :",text)   // un parametro - 'text'
 
 // forma parametrica errata        
#define WRONG_DEF(p1, p2, p3, p4, p5, p6, p7, p8, p9)   p1+p2+p3+p4 // più di 8 parametri da p1 a p9

The #undef directive

The #undef directive cancels declaration of the macro substitution, defined before.

Esempio:

#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();
  }
 
/* Risultato:
 MACRO is defined in func1
 MACRO is not defined in func2
*/

Vedi anche

Identificatori, Costanti Carattere