Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Langue C

Préprocesseur C++ : Comment les directives façonnent votre code

Les préprocesseurs sont les directives qui donnent des instructions au compilateur pour pré-traiter l'information avant que la compilation réelle ne commence.

Toutes les directives de préprocesseur commencent par #, et seuls des caractères d'espacement peuvent apparaître avant une directive de préprocesseur sur une ligne. Les directives de préprocesseur ne sont pas des instructions C++, donc elles ne se terminent pas par un point-virgule (;).

Vous avez déjà vu une directive #include dans tous les exemples. Cette macro est utilisée pour inclure un fichier d'en-tête dans le fichier source.

Il y a 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 est appelée un macro et la forme générale de la directive est :

#define nom_macro texte_remplacement

Quand cette ligne apparaît dans un fichier, toutes les occurrences subséquentes du macro dans ce fichier seront remplacées par texte_remplacement avant que le programme ne soit compilé. Par exemple :

#include <iostream>
using namespace std;

#define PI 3.14159

int main() {
    cout << "Valeur de PI : " << PI << endl;
    return 0;
}

Maintenant, faisons le pré-traitement de ce code pour voir le résultat en supposant que nous ayons le fichier de code source. Compilons-le avec l'option -E et redirigeons le résultat vers test.p. Maintenant, si vous vérifiez test.p, il aura beaucoup d'informations et au fond, vous trouverez la valeur remplacée comme suit :

$ gcc -E test.cpp > test.p
...
int main() {
    cout << "Valeur de PI : " << 3.14159 << endl;
    return 0;
}

Macros de type fonction

Vous pouvez utiliser #define pour définir un macro qui prendra des arguments 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 << "Le minimum est " << MIN(i, j) << endl;
    return 0;
}

Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant :

Le minimum est 30

Compilation conditionnelle

Il y a plusieurs directives qui peuvent être utilisées pour compiler sélectivement des portions du code source de votre programme. Ce processus s'appelle la compilation conditionnelle.

La construction conditionnelle du préprocesseur ressemble beaucoup à la structure de sélection 'if'. Considérez le code de préprocesseur suivant :

#ifndef NULL
#define NULL 0
#endif

Vous pouvez compiler un programme pour des fins de débogage. Vous pouvez aussi activer ou désactiver le débogage en utilisant un seul macro comme suit :

#ifdef DEBUG
cerr << "Variable x = " << x << endl;
#endif

Cela cause l'instruction cerr à être compilée 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 portion du programme comme suit :

#if 0
code empêché de compiler
#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 : À l'intérieur de la fonction main" << endl;
    #endif
    #if 0
    /* Cette partie est commentée */
    cout << MKSTR(HELLO C++) << endl;
    #endif
    cout << "Le minimum est " << MIN(i, j) << endl;
    #ifdef DEBUG
    cerr << "Trace : Sortie de la fonction main" << endl;
    #endif
    return 0;
}

Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant :

Le minimum est 30
Trace : À l'intérieur de la fonction main
Trace : Sortie de la fonction main

Les opérateurs # et ##

Les opérateurs de préprocesseur # et ## sont disponibles en C++ et ANSI/ISO C. L'opérateur # cause un jeton de texte_remplacement à être converti 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++ transforme la ligne :

cout << MKSTR(HELLO C++) << endl;

La ligne ci-dessus sera transformée en la 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

Quand CONCAT apparaît dans le programme, ses arguments sont concaténés et utilisés pour remplacer le 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 la ligne suivante :

cout << xy;

Macros C++ prédéfinis

C++ fournit un certain nombre de macros prédéfinis mentionnés ci-dessous :

N°Macro et description
1

__LINE__

Contient le numéro de ligne courant du programme lors de la compilation.

2

__FILE__

Contient le nom de fichier courant du programme lors de la compilation.

3

__DATE__

Contient une chaîne de la forme mois/jour/année qui est la date de traduction du fichier source en code objet.

4

__TIME__

Contient une chaîne de la forme heure:minute:seconde qui est l'heure à laquelle le programme a été compilé.

Voyons un exemple pour tous les macros ci-dessus :

#include <iostream>
using namespace std;

int main() {
    cout << "Valeur de __LINE__ : " << __LINE__ << endl;
    cout << "Valeur de __FILE__ : " << __FILE__ << endl;
    cout << "Valeur de __DATE__ : " << __DATE__ << endl;
    cout << "Valeur de __TIME__ : " << __TIME__ << endl;
    return 0;
}

Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant :

Valeur de __LINE__ : 6
Valeur de __FILE__ : test.cpp
Valeur de __DATE__ : Feb 28 2011
Valeur de __TIME__ : 18:52:48

Langue C

  1. Maîtriser les directives de préprocesseur C# : Guide pratique
  2. Comprendre les types de données C++ : Fondamentaux, modificateurs et bonnes pratiques
  3. Maîtriser les opérateurs C++ : Guide complet avec exemples pratiques
  4. Commentaires C++ : Bonnes pratiques pour un code lisible et maintenable
  5. Comprendre les constructeurs C++ : Par défaut, paramétrés et de copie expliqués
  6. Maîtriser les templates de classe en C++ : Guide pratique
  7. Comprendre le préprocesseur C (CPP) : Comment il simplifie la compilation
  8. Langage C++ : Vue d'ensemble et caractéristiques clés
  9. Constantes et littéraux en C++ : Types, syntaxe et bonnes pratiques