En langage C, un programme ne se limite pas à un simple fichier. Dès que la taille d’un projet augmente, il devient indispensable de structurer le code, de réutiliser des fonctions existantes et de séparer les responsabilités
Le langage C repose pour cela sur un système de bibliothèques et de fichiers organisés (.h et .c), reliés entre eux grâce à la directive #include. Comprendre ce mécanisme est fondamental : il permet non seulement d’utiliser les fonctions standard du langage, mais aussi de créer ses propres bibliothèques, claires, maintenables et professionnelles.
Ce chapitre explique comment fonctionne #include, à quoi servent les librairies, et comment organiser correctement un programme C en plusieurs fichiers.
En C, on ne réécrit pas tout soi-même. Le langage met à disposition des bibliothèques : des ensembles de fonctions déjà écrites, testées et optimisées.
Exemples de fonctions fournies par des bibliothèques :
printf() → affichage à l’écranscanf() → lecture claviersqrt() → racine carréestrlen() → longueur d’une chaîneCes fonctions n’existent pas par magie : il faut dire au compilateur où elles sont déclarées.
#includeLa directive #include sert à insérer le contenu d’un fichier dans un autre fichier avant la compilation.
Exemple :
#include <stdio.h>
Cela signifie :
« Inclure les déclarations des fonctions d’entrée/sortie standard »
Sans cette ligne :
printf("Bonjour");
le compilateur ne sait pas ce qu’est printf.
#include <...> ou #include "..." : quelle différence ?#include <stdio.h>Exemples courants :
#include <stdio.h> // printf, scanf
#include <stdlib.h> // malloc, rand, exit
#include <math.h> // sqrt, pow
#include <string.h> // strlen, strcmp
#include "monfichier.h"Exemple :
#include "utils.h"
.h ?Un fichier .h (header / en-tête) déclare ce qui existe, mais ne contient pas le code complet.
Il sert à :
math_utils.h#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int addition(int a, int b);
int soustraction(int a, int b);
#endif
➡️ Ici, on annonce que ces fonctions existent quelque part.
.c ?Le fichier .c contient le code réel, c’est-à-dire les définitions des fonctions.
math_utils.c#include "math_utils.h"
int addition(int a, int b) {
return a + b;
}
int soustraction(int a, int b) {
return a - b;
}
➡️ Le .c implémente ce qui a été annoncé dans le .h.
.h et .c ?Cette séparation permet :
Dans le
.h: ce que le programme peut utiliser Dans le.c: comment cela fonctionne
main.cmain.c#include <stdio.h>
#include "math_utils.h"
int main(void) {
int resultat;
resultat = addition(5, 3);
printf("Addition : %d\n", resultat);
resultat = soustraction(10, 4);
printf("Soustraction : %d\n", resultat);
return 0;
}
#ifndef / #define / #endifDans un .h, ces lignes évitent l’inclusion multiple.
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
...
#endif
Sans ça :
➡️ C’est une protection obligatoire dans tout fichier .h.
Commande classique avec GCC :
gcc main.c math_utils.c -o programme
Explication :
main.c → programme principalmath_utils.c → fonctions externes-o programme → nom de l’exécutable⚠️ On ne compile jamais les .h, seulement les .c.
.h.h dans le .c.h et le .c.c dans un autre .c#ifndef#include insère du code avant compilation<...> → bibliothèques standard"..." → fichiers du projet.h → déclarations.c → implémentations.c est compilé séparément.h sert de contrat