Préprocesseur C++
Les préprocesseurs sont des instructions qui indiquent au compilateur le prétraitement qui doit être effectué avant la compilation proprement dite.
Toutes les directives du préprocesseur commencent par un signe dièse (#), et seuls les caractères d'espace peuvent apparaître avant les directives du préprocesseur. Les directives de prétraitement ne sont pas des instructions C++, elles ne se terminent donc pas par un point-virgule (;).
Nous avons vu que tous les exemples précédents ont la directive #include. Cette macro est utilisée pour inclure des fichiers d'en-tête dans les fichiers source.
C++ prend également en charge de nombreuses instructions de prétraitement, telles que #include, #define, #if, #else, #line, etc. Examinons ensemble ces instructions importantes.
#define preprocessing
La directive de prétraitement #define est utilisée pour créer des constantes symboliques. Cette constante symbolique est généralement appelée la macro La forme générale de l'instruction est :
#define macro-name replacement-text
Lorsque cette ligne de code apparaît dans un fichier, toutes les macros suivantes qui apparaissent dans le fichier seront remplacées. avec du texte de remplacement 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, testons ce code et voyons les résultats du prétraitement. En supposant que le fichier de code source existe déjà, utilisez l'option -E pour compiler et rediriger les résultats vers test.p. Maintenant, si vous regardez le fichier test.p, vous verrez qu'il contient déjà beaucoup d'informations, et les valeurs au bas du fichier ont été modifiées comme suit :
$gcc -E test.cpp > test.p ... int main () { cout << "Value of PI :" << 3.14159 << endl; return 0; }
Fonction Macro
Vous pouvez utiliser #define pour définir une macro avec des paramètres comme celui-ci :
#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; }
Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :
The minimum is 30
Compilation conditionnelle
Il existe plusieurs instructions qui peuvent être utilisées pour compiler sélectivement des parties du code source du programme. Ce processus est appelé compilation conditionnelle.
La structure du préprocesseur conditionnel est très similaire à la structure de sélection if. Veuillez consulter le code du préprocesseur suivant :
#ifndef NULL #define NULL 0 #endif
Vous ne pouvez compiler que pendant le débogage. Le commutateur de débogage peut être implémenté à l'aide d'une macro, comme indiqué ci-dessous :
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
Si dans la directive #ifdef DEBUG. Si la constante symbolique DEBUG a été définie auparavant, l'instruction cerr dans le programme sera compilée. Vous pouvez commenter une partie du programme en utilisant les instructions #if 0 comme ceci :
#if 0 不进行编译的代码 #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 /* 这是注释部分 */ 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; }
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultats suivants :
Trace: Inside main function The minimum is 30 Trace: Coming out of main function
Opérateurs # et ## Les opérateurs de préprocesseur
# et ## sont disponibles en C++ et ANSI/ISO C. L'opérateur # convertit le jeton de texte de remplacement en chaîne entre guillemets.
Regardez la définition de la macro ci-dessous :
#include <iostream> using namespace std; #define MKSTR( x ) #x int main () { cout << MKSTR(HELLO C++) << endl; return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant :
HELLO C++
Voyons ce que c'est Comment ça marche . Il n'est pas difficile de comprendre que le préprocesseur C++ convertit la ligne suivante :
cout << MKSTR(HELLO C++) << endl;
en :
cout << "HELLO C++" << endl;
## l'opérateur est utilisé pour connecter deux jetons. Voici un exemple :
#define CONCAT( x, y ) x ## y
Lorsque CONCAT apparaît dans un programme, ses arguments sont concaténés et utilisés à la place de la macro. Par exemple, CONCAT(HELLO, C++) dans le programme sera remplacé par « HELLO C++ », comme indiqué dans l'exemple ci-dessous.
#include <iostream> using namespace std; #define concat(a, b) a ## b int main() { int xy = 100; cout << concat(x, y); return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :
100
Voyons comment ça marche. Il n'est pas difficile de comprendre que le préprocesseur C++ convertit la ligne suivante :
cout << concat(x, y);
en :
cout << xy;
Les macros prédéfinies en C++
C++ fournit le tableau suivant Quelques-unes des macros prédéfinies :
宏 | 描述 |
---|---|
__LINE__ | 这会在程序编译时包含当前行号。 |
__FILE__ | 这会在程序编译时包含当前文件名。 |
__DATE__ | 这会包含一个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。 |
__TIME__ | 这会包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。 |
Voyons une instance de ces 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; }
Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48