« Introduction au langage C/Le préprocesseur » : différence entre les versions

Contenu supprimé Contenu ajouté
Thierry46 (discussion | contributions)
→‎Opérateurs # et ## : Rédaction et exemples
Thierry46 (discussion | contributions)
Déplacement chapitre sur # et ##
Ligne 91 :
* __LINE__ : Ligne courante.
* __STDC_VERSION__ : permet de connaître la version du compilateur utilisé : entier long qui vaut 199901L si le compilateur respecte la norme C99.
 
===Opérateurs # et ##===
 
L'opérateur # précédant un nom de constante symbolique peut servir à préparer l'impression d'expressions contenant des délimiteurs de chaîne " ou des caractères d'échappement comme \n.
 
L'extrait de code source :
<source lang=c>
#define STR(s) #s
/*
Pour imprimer une chaine contenant des " et
des caracteres d'echappement ex : \n
*/
(void)puts(STR((void)puts("\n");));
</source>
 
Sera expansé par le préprocesseur en :
<source lang=c>
(void)puts("(void)puts(\"\\n\");");
</source>
 
Cet opérateur # peut aussi servir pour émettre un message plus précis par la fonction <tt>perror</tt>. Le message d'erreur peut alors contenir le nom du fichier source dans lequel s'est produit l'erreur ainsi que le numéro de la ligne concernée
 
<source lang=c>
/*
Transformation de la constante numerique __LINE__ en chaine
de caractere par le preprocesseur a l'aide de l'operateur #.
Remarquer que STR(__LINE__) sera expanse en __LINE__ et non
en numero de ligne.
*/
(void)puts("Transformation de constante numerique en chaine");
#define STR(s) #s
#define XSTR(s) STR(s)
(void)printf("__LINE__ = %d\n", __LINE__);
(void)printf("STR(__LINE__) = %s\n", STR(__LINE__));
(void)printf("XSTR(__LINE__) = %s\n", XSTR(__LINE__));
 
/* Utilisation avec perror. Evite un sprintf dans buffer */
(void)puts("\nApplication a perror");
errno = EDOM; /* Simulation erreur sur domaine de fonction */
perror(__FILE__": ligne " XSTR(__LINE__));
</source>
 
Donnera à l'exécution :
<pre>
Transformation de constante numerique en chaine
__LINE__ = 42
STR(__LINE__) = __LINE__
XSTR(__LINE__) = 44
 
Application a perror
macro.c: ligne 49: Numerical argument out of domain
</pre>
 
L'opérateur ## permet de concaténer une chaîne de caractère à un paramètre de macro :
<source lang=c>
int x1 = 1;
int x2 = 2;
 
/* Exemple de macro utilisant la concatenation de variables */
#define debug(s, t) \
(void)printf("x" # s "= %d, x" # t "= %d\n", \
x ## s, x ## t)
 
(void)puts("\nCreation de variable par concatenation de chaine");
debug(1, 2);
</source>
 
Sera expansé par le préprocesseur en :
<source lang=c>
int x1 = 1;
int x2 = 2;
(void)puts("\nCreation de variable par concatenation de chaine");
(void)printf("x" "1" "= %d, x" "2" "= %d\n", x1, x2);
</source>
 
Donnera à l'exécution :
<pre>
Creation de variable par concatenation de chaine
x1= 1, x2= 2
</pre>
 
L'utilisation de cet opérateur ## peut cependant rendre le code obscur. L'utilisation d'une fonction peut être plus lisible par un programmeur habitué à d'autres langage que le C.
 
===Remarques qualité===
Ligne 395 ⟶ 313 :
#endif
</source>
 
===Opérateurs # et ##===
 
L'opérateur # précédant un nom de constante symbolique peut servir à préparer l'impression d'expressions contenant des délimiteurs de chaîne " ou des caractères d'échappement comme \n.
 
L'extrait de code source :
<source lang=c>
#define STR(s) #s
/*
Pour imprimer une chaine contenant des " et
des caracteres d'echappement ex : \n
*/
(void)puts(STR((void)puts("\n");));
</source>
 
Sera expansé par le préprocesseur en :
<source lang=c>
(void)puts("(void)puts(\"\\n\");");
</source>
 
Cet opérateur # peut aussi servir pour émettre un message plus précis par la fonction <tt>perror</tt>. Le message d'erreur peut alors contenir le nom du fichier source dans lequel s'est produit l'erreur ainsi que le numéro de la ligne concernée
 
<source lang=c>
/*
Transformation de la constante numerique __LINE__ en chaine
de caractere par le preprocesseur a l'aide de l'operateur #.
Remarquer que STR(__LINE__) sera expanse en __LINE__ et non
en numero de ligne.
*/
(void)puts("Transformation de constante numerique en chaine");
#define STR(s) #s
#define XSTR(s) STR(s)
(void)printf("__LINE__ = %d\n", __LINE__);
(void)printf("STR(__LINE__) = %s\n", STR(__LINE__));
(void)printf("XSTR(__LINE__) = %s\n", XSTR(__LINE__));
 
/* Utilisation avec perror. Evite un sprintf dans buffer */
(void)puts("\nApplication a perror");
errno = EDOM; /* Simulation erreur sur domaine de fonction */
perror(__FILE__": ligne " XSTR(__LINE__));
</source>
 
Donnera à l'exécution :
<pre>
Transformation de constante numerique en chaine
__LINE__ = 42
STR(__LINE__) = __LINE__
XSTR(__LINE__) = 44
 
Application a perror
macro.c: ligne 49: Numerical argument out of domain
</pre>
 
L'opérateur ## permet de concaténer une chaîne de caractère à un paramètre de macro :
<source lang=c>
int x1 = 1;
int x2 = 2;
 
/* Exemple de macro utilisant la concatenation de variables */
#define debug(s, t) \
(void)printf("x" # s "= %d, x" # t "= %d\n", \
x ## s, x ## t)
 
(void)puts("\nCreation de variable par concatenation de chaine");
debug(1, 2);
</source>
 
Sera expansé par le préprocesseur en :
<source lang=c>
int x1 = 1;
int x2 = 2;
(void)puts("\nCreation de variable par concatenation de chaine");
(void)printf("x" "1" "= %d, x" "2" "= %d\n", x1, x2);
</source>
 
Donnera à l'exécution :
<pre>
Creation de variable par concatenation de chaine
x1= 1, x2= 2
</pre>
 
L'utilisation de cet opérateur ## peut cependant rendre le code obscur. L'utilisation d'une fonction peut être plus lisible par un programmeur habitué à d'autres langage que le C.
 
=== #pragma ===