adplus-dvertising

Macros et pré-processeurs en C

Macros et pré-processeurs en C

Dans un programme C, toutes les lignes commençant par # sont traitées par le préprocesseur, programme spécial appelé par le compilateur. Dans un terme très basique, le préprocesseur prend un programme C et produit un autre programme C sans #.

Voici quelques faits intéressants sur les pré-processeurs en C.

 Lorsque nous utilisons la directive include, le contenu du fichier d'en-tête inclus (après prétraitement) est copié dans le fichier actuel.
Les crochets angulaires  < et > indiquent au préprocesseur de rechercher dans le dossier standard où sont stockés tous les fichiers d’en-tête. Les guillemets doubles " et " indiquent au préprocesseur de rechercher dans le dossier en cours (répertoire en cours).

 Lorsque nous utilisons define pour une constante, le préprocesseur génère un programme en C dans lequel la constante définie est recherchée et les jetons correspondants remplacés par l'expression donnée. Par exemple, dans le programme suivant, max est défini sur 100.

Exemple 1 :
                                #include <stdio.h>
                                #define max 100
                                int main(void)
                                {
                                    printf("max = %d \n", max);

                                    return 0;
                                }
                            
max = 100

  Les macros peuvent prendre la fonction comme arguments, les arguments ne sont pas vérifiés pour le type de données. Par exemple, la macro INCREMENT(x) suivante peut être utilisée pour x de n'importe quel type de données.

Exemple 2 :
                                #include <stdio.h>
                                #define INCREMENT(x) ++x
                                int main(void)
                                {
                                    char *ptr = "Bonjour"; 
                                    int x = 5; 
                                    printf("%s  \n", INCREMENT(ptr)); 
                                    printf("%d", INCREMENT(x)); 

                                    return 0;
                                }
                            
onjour
6

  Les arguments de macro ne sont pas évalués avant l'expansion de la macro. Par exemple considérons le programme suivant

Exemple 3 :
                                #include <stdio.h>
                                #define PRODUIT(a, b) a*b 
                                int main(void)
                                {
                                    // La macro est développée comme 2 + 3 * 3 + 5, pas comme 5*8
                                    printf("%d", PRODUIT(2+3, 3+5)); 

                                    return 0;
                                }
                            
16

Le problème précédent peut être résolu en utilisant le programme suivant

Exemple 4 :
                                #include <stdio.h>
                                #define PRODUIT(a, b) (a)*(b) 
                                int main(void)
                                {
                                    // La macro est développée comme 2 + 3 * 3 + 5, pas comme 5*8
                                    printf("%d", PRODUIT(2+3, 3+5)); 

                                    return 0;
                                }
                            
40

  Les jetons transmis aux macros peuvent être concaténés à l'aide de l'opérateur ## appelé opérateur de jeton.

Exemple 5 :
                                #include <stdio.h>
                                #define CONCAT(a, b) a##b 
                                int main(void)
                                {
                                    printf("%d", CONCAT(2, 3)); 

                                    return 0;
                                }
                            
23

  Un jeton transmis à une macro peut être converti en une chaîne en utilisant # avant celui-ci.

Exemple 6 :
                                #include <stdio.h>
                                #define toString(a) #a 
                                int main(void)
                                {
                                    printf("%s ", toString(2)); 

                                    return 0;
                                }
                            
2

  Les macros peuvent être écrites sur plusieurs lignes à l’aide de "\". La dernière ligne n’a pas besoin de "\".

Exemple 7 :
                                #include <stdio.h>
                                #define AFFICHER(i, limit)  \
                                            while (i < limit)       \
                                            {                       \
                                                printf("%d \n", i); \
                                                i++;                \
                                            }
                                int main(void)
                                {
                                    int i = 2;
                                    AFFICHER(i,8); 

                                    return 0;
                                }
                            
2
3
4
5
6
7

  Les macros avec arguments doivent être évitées car elles posent parfois des problèmes. Et les fonctions inline devraient être préférées car il existe une évaluation des paramètres de vérification de type dans les fonctions en ligne.
Par exemple, considérons le programme suivant. À première vue, la sortie semble être 1, mais il produit 36 comme sortie.

Exemple 8 :
                                #include <stdio.h>
                                #define CARREE(x) x*x 
                                int main(void)
                                {
                                    // développée comme 36 / 6 * 6
                                    int x = 36/CARREE(6);
                                    printf("%d", x); 

                                    return 0;
                                }
                            
36

Si nous utilisons des fonctions inline, nous obtenons le résultat attendu.

Exemple 9 :
                                #include <stdio.h>
                                inline CARREE(int x){ return x * x; } 
                                int main(void)
                                {
                                    int x = 36/CARREE(6);
                                    printf("%d", x); 

                                    return 0;
                                }
                            
1

  Un fichier d'en-tête peut être inclus plusieurs fois, directement ou indirectement, ce qui entraîne des problèmes de redéclaration des mêmes variables / fonctions. Pour éviter ce problème, des directives telles que defined, ifdef et ifndef sont utilisées.

  Certaines macros standard peuvent être utilisées pour afficher le fichier de programme (__FILE__), la date de compilation (__DATE__), l'heure de compilation (__TIME__) et le numéro de ligne dans le code C (__LINE__).

Exemple 10 :
                                #include <stdio.h>

                                int main(void)
                                {
                                    printf("Fichier actuel : %s ",__FILE__);
                                    printf("Date actuelle : %s ",__DATE__);
                                    printf("Heure actuelle : %s ",__TIME__);
                                    printf("Numéro de ligne : %d ",__LINE__);

                                    return 0;
                                }
                            
Fichier actuel : prog.c
Date actuelle : Aug 27 2019
Heure actuelle : 12:44:21
Numéro de ligne : 8

  Nous pouvons supprimer les macros déjà définies en utilisant #undef NOM_MACRO

Exemple 11 :
                                #include <stdio.h>

                                #define MAX 100

                                int main(void)
                                {
                                    printf("%d",MAX);

                                    //supprimer la macro définie LIMIT
                                    #undef MAX;

                                    printf("%d",MAX);

                                    return 0;
                                }
                            
prog.c:12:18: error: use of undeclared identifier 'MAX'

Partager ce cours avec tes amis :
Rédigé par ESSADDOUKI Mostafa
ESSADDOUKI
The education of the 21st century opens up opportunities to not merely teach, but to coach, mentor, nurture and inspire.