Académique Documents
Professionnel Documents
Culture Documents
Introduction
La compilation consiste à traduire le programme source (ou le contenu d’un fichier source) en
langage machine, en faisant appel à un programme nommé compilateur. La compilation se
décompose en fait en 4 phases successives : Le préprocesseur, la compilation, l’assemblage, l’édition
des liens.
1. Enlèvement de commentaires
Les commentaires sont destinés à faciliter la compréhension du code source lors de la relecture. Ils
ne sont d’aucune utilité au compilateur, et il est naturel qu’ils n’apparaissent pas dans le code source
qui lui est destiné. Par conséquent, le pré-processeur retire les caractères compris entre /* et */.
2. Inclusion de fichiers
• La directive #include sert à inclure les fichiers, des modules que l’on va utiliser ou écrire.
Le pré-processeur fait simplement un copier-coller du contenu du fichier inclut dans le fichier
contenant le #include.
Cette directive possède deux syntaxes:
#include <nom_fichier>
3. Substitutions
• la directive #define sert à définir des symboles et des macros (c’est à dire des bout de code
qui seront recopiées tels-quels dans le code C)
• Exemples de définitions de symboles:
o #define TAILLE 5
demande de substituer au symbole TAILLE (constante) par le texte 5, et cela chaque
fois que ce symbole apparaîtra dans la suite du fichier source.
o #define entier int
placée en début de programme, permettra d’écrire en français les déclarations de
variables entières.
Par exemple, entier a, b ; sera remplacée par : int a, b ;
o #define bonjour printf("bonjour")
o ça permet de résumer en un seul mot une instruction en C : bonjour est remplacé par
printf("bonjour")
Tous les symboles carre(x) seront remplacés par x*x par le préprocesseur
o #define dif(a,b) a-b
Dans cet exemple, la macro contient deux paramètres
Attention : le programme n'est pas compilé durant le traitement du pré-processeur. Si des erreurs
existent, elles seront toujours présentes après la phase de pré-processing. Le pré-processeur ne fait
que réécrire le programme selon des règles que vous précisez.
Exemple :
#include <stdio.h>
#include <stdlib.h>
/* Définition de quelques macros */
#define FALSE 0 /*simuler les variabes booléennes qui
n’existaient pas dans les premières
versions du C*/
#define TRUE 1
#define BOOL int
#define MINI( a, b ) ((a)<(b) ? (a) : (b))
#define MAXI( a, b ) ((a)>(b) ? (a) : (b))
int main() {
int state = 1;
if ( state == 0 ) {
printf( "Maximum(3, 5) == %d", ((3)>(5) ? (3) : (5)) );
} else {
printf( "Minimum(3, 5) == %d", ((3)<(5) ? (3) : (5)) );
}
return 0;
}
4. L’instruction undef
Cette instruction permet d'annuler une définition de macro. Il suffit juste de spécifier le nom de la
macro à invalider et ce directement après l'instruction.
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = 123;
#define a 456
printf( "a = %d\n", a );
#undef a
a = 456
a = 123
Nom des
Développement de la macro associée.
macros
6. Compilation conditionnelle
Un certain nombre de directives permettent de sélectionner (inclusion ou exclusion) des
portions du fichier source dans le texte qui est analysé par le préprocesseur.
Cette sélection se fait à partir des lignes de directives suivantes : #if, #ifdef, #ifndef, #else, #endif
Ces directives se classent en deux catégories en fonction de la condition qui régit l’incorporation :
existence ou inexistence de symboles ;
valeur d’une expression.
#ifdef PI
instructions 1 ...
#else
instructions 2 ...
#endif
Dans cet exemple, si la constante PI est définie (c’est à dire #define PI existant), alors la partie
instructions1 sera incluse dans le code, sinon instructions 2).
Exemple 2:
#define VX #define VX
..... .....
#ifdef VX #ifndef VX
instructions 1 instructions 1
#else #else
instructions 2 instructions 2
#endif #endif
Remarque:
Il existe un opérateur noté defined qu’on peut utiliser dans les exemples précédents.
#if defined(PI)
instructions 1 ...
#else
instructions 2 ...
#endif
Résumé:
#if defined identifier #ifdef identifier
Remarque : le ! est un opérateur du pré-processeur qui renvoie 1 si son opérande est 0 et renvoie 0
dans tous les autres cas.
#define CODE 1
.....
#if CODE == 1
instructions 1
#endif
#if CODE == 2
instructions 2
#endif
Dans cet exemple, ce sont les instructions 1 qui seront incorporées par le préprocesseur. Mais il
s’agirait des instructions 2 si nous remplacions la première directive par : #define CODE 2
Notez qu’il existe également une directive #elif qui permet de condenser les choix imbriqués.
Par exemple, nos précédentes instructions pourraient s’écrire :
#define CODE 1
.....
#if CODE == 1
instructions 1
#elif CODE == 2
instructions 2
#endif
II. La compilation
Au cours de cette étape, le fichier engendré par le préprocesseur est traduit en assembleur, c'est à
dire en une suite d'instructions qui sont chacune associées à une fonctionnalité du microprocesseur
(faire une addition, une comparaison, etc.).
Remarque :
Le compilateur C a pour particularité de faire de la compilation séparée : cela signifie que chaque
fichier source est compilé sans regarder les autres fichiers, même s’ils font partie du même
programme. Pour compiler un fichier C, le compilateur a juste besoin de connaitre les prototypes de
toutes les fonctions utilisées dans ce fichier, mais il n’a pas besoin d’avoir à sa disposition le code de
ces fonctions externes. Les prototypes des fonctions sont définies dans des fichiers .h, qui sont inclus
par le pré-processeur dans le fichier C qui les utilise via la directive #include
III. L’assembleur
L’assembleur prend un fichier écrit en langage assembleur et le traduit en code binaire (langage
machine) : instructions directement compréhensibles par le processeur.
Le fichier produit par l'assemblage est appelé fichier objet (extension .o) qui est totalement
incompréhensible par l’humain.
Résumé :
V. Exemples
Exemple 1:
Exemple 2:
Le programme est divisé en trois fichiers :
- La somme i+2 est réalisée par une fonction f, qui est écrite dans le fichier f1.c
- La racine carrée de j est réalisée par une fonction g, qui est écrite dans le fichier f2.c
- Le programme principal qui calcule f(i)*g(j) se trouve dans le fichier p1.c
- On veut construire le programme qui affiche le résultat