Préprocesseur C ++
Les préprocesseurs sont les directives, qui donnent des instructions au compilateur pour prétraiter les informations avant le début de la compilation réelle.
Toutes les directives de préprocesseur commencent par # et seuls les caractères d'espace blanc peuvent apparaître avant une directive de préprocesseur sur une ligne. Les directives de préprocesseur ne sont pas des instructions C ++, elles ne se terminent donc pas par un point-virgule (;).
Vous avez déjà vu un #includedirective dans tous les exemples. Cette macro est utilisée pour inclure un fichier d'en-tête dans le fichier source.
Il existe un certain nombre de directives de préprocesseur supportées par C ++ comme #include, #define, #if, #else, #line, etc. Voyons les directives importantes -
Le préprocesseur #define
La directive de préprocesseur #define crée des constantes symboliques. La constante symbolique s'appelle unmacro et la forme générale de la directive est -
#define macro-name replacement-text
Lorsque cette ligne apparaît dans un fichier, toutes les occurrences ultérieures de macro dans ce fichier seront remplacées par remplacement-text avant la compilation du programme. Par exemple -
#include <iostream>
using namespace std;
#define PI 3.14159
int main () {
cout << "Value of PI :" << PI << endl;
return 0;
}
Maintenant, faisons le prétraitement de ce code pour voir le résultat en supposant que nous avons le fichier de code source. Alors compilons-le avec l'option -E et redirigeons le résultat vers test.p. Maintenant, si vous vérifiez test.p, il contiendra beaucoup d'informations et en bas, vous trouverez la valeur remplacée comme suit -
$gcc -E test.cpp > test.p
...
int main () {
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
Macros fonctionnelles
Vous pouvez utiliser #define pour définir une macro qui prendra l'argument comme suit -
#include <iostream>
using namespace std;
#define MIN(a,b) (((a)<(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 30;
cout <<"The minimum is " << MIN(i, j) << endl;
return 0;
}
Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant -
The minimum is 30
Compilation conditionnelle
Il existe plusieurs directives qui peuvent être utilisées pour compiler des portions sélectives du code source de votre programme. Ce processus est appelé compilation conditionnelle.
La construction du préprocesseur conditionnel ressemble beaucoup à la structure de sélection «si». Considérez le code de préprocesseur suivant -
#ifndef NULL
#define NULL 0
#endif
Vous pouvez compiler un programme à des fins de débogage. Vous pouvez également activer ou désactiver le débogage à l'aide d'une seule macro comme suit -
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
Cela provoque le cerrinstruction à compiler dans le programme si la constante symbolique DEBUG a été définie avant la directive #ifdef DEBUG. Vous pouvez utiliser l'instruction #if 0 pour commenter une partie du programme comme suit -
#if 0
code prevented from compiling
#endif
Essayons l'exemple suivant -
#include <iostream>
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* This is commented part */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant -
The minimum is 30
Trace: Inside main function
Trace: Coming out of main function
Les opérateurs # et ##
Les opérateurs de préprocesseur # et ## sont disponibles en C ++ et ANSI / ISO C. L'opérateur # entraîne la conversion d'un jeton de texte de remplacement en une chaîne entourée de guillemets.
Considérez la définition de macro suivante -
#include <iostream>
using namespace std;
#define MKSTR( x ) #x
int main () {
cout << MKSTR(HELLO C++) << endl;
return 0;
}
Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant -
HELLO C++
Voyons comment cela a fonctionné. Il est simple de comprendre que le préprocesseur C ++ tourne la ligne -
cout << MKSTR(HELLO C++) << endl;
La ligne ci-dessus sera transformée en ligne suivante -
cout << "HELLO C++" << endl;
L'opérateur ## est utilisé pour concaténer deux jetons. Voici un exemple -
#define CONCAT( x, y ) x ## y
Lorsque CONCAT apparaît dans le programme, ses arguments sont concaténés et utilisés pour remplacer la macro. Par exemple, CONCAT (HELLO, C ++) est remplacé par "HELLO C ++" dans le programme comme suit.
#include <iostream>
using namespace std;
#define concat(a, b) a ## b
int main() {
int xy = 100;
cout << concat(x, y);
return 0;
}
Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant -
100
Voyons comment cela a fonctionné. Il est simple de comprendre que le préprocesseur C ++ transforme -
cout << concat(x, y);
La ligne ci-dessus sera transformée en ligne suivante -
cout << xy;
Macros C ++ prédéfinies
C ++ fournit un certain nombre de macros prédéfinies mentionnées ci-dessous -
Sr.Non | Macro et description |
---|---|
1 | __LINE__ Il contient le numéro de ligne actuel du programme lors de sa compilation. |
2 | __FILE__ Il contient le nom de fichier actuel du programme lors de sa compilation. |
3 | __DATE__ Celui-ci contient une chaîne de la forme mois / jour / année qui est la date de la traduction du fichier source en code objet. |
4 | __TIME__ Celui-ci contient une chaîne de la forme heure: minute: seconde qui correspond à l'heure à laquelle le programme a été compilé. |
Voyons un exemple pour toutes les macros ci-dessus -
#include <iostream>
using namespace std;
int main () {
cout << "Value of __LINE__ : " << __LINE__ << endl;
cout << "Value of __FILE__ : " << __FILE__ << endl;
cout << "Value of __DATE__ : " << __DATE__ << endl;
cout << "Value of __TIME__ : " << __TIME__ << endl;
return 0;
}
Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant -
Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48