14 KiB
Sommaire — Cours complet de programmation en C
Périmètre du cours : C pur, du niveau débutant jusqu’à un niveau avancé, avec une ouverture vers la portabilité, les environnements d’exécution, les outils de build, la distribution, l’ABI/FFI, le réseau, les threads, la bibliothèque standard, ainsi que les référentiels de qualité et de sécurité.
Chapitre 0 — Introduction générale
0.1. Présentation du langage C
0.2. Historique du C
0.3. Pourquoi apprendre le C aujourd’hui
0.4. Domaines d’usage du C
0.5. Ce que le C permet, et ce qu’il ne fait pas à votre place
0.6. Programme minimal : main et premier printf
Chapitre 1 — Normes du langage C
1.1. Qu’est-ce qu’une norme
1.2. ANSI C / C89 / C90
1.3. C95
1.4. C99
1.5. C11
1.6. C17 / C18
1.7. C23
1.8. Différences majeures entre les versions
1.9. Comment choisir une norme dans un compilateur
1.10. Extensions de compilateur vs C standard
Chapitre 2 — Environnements et portabilité
2.1. C hébergé vs C freestanding
2.2. Plateformes et systèmes
2.3. Architecture vs système
2.4. Endianness
2.5. Taille des types
2.6. Dépendances système
2.7. Ce qui est portable
2.8. Abstraction
2.9. Bonnes pratiques
Chapitre 3 — Outils et chaîne de compilation
3.1. Compilateurs : gcc, clang, autres
3.2. Préprocesseur, compilation, assemblage, édition de liens
3.3. Fichiers source, objets, exécutables
3.4. Warnings, erreurs, diagnostics
3.5. Options importantes du compilateur
3.6. Standards de compilation (-std=c99, -std=c11, etc.)
3.7. Fichiers de debug
3.8. Compilation séparée
3.9. Compilation croisée
Chapitre 4 — Structure d’un programme C
4.1. Fonction main
4.2. Instructions et blocs
4.3. Commentaires
4.4. Déclarations
4.5. Définitions
4.6. En-têtes .h et sources .c
4.7. Organisation minimale d’un projet
Chapitre 5 — Variables, objets, portée et durée de vie
5.1. Déclaration et initialisation
5.2. Variables locales
5.3. Variables globales
5.4. Variables de fichier
5.5. Variables static
5.6. Variables extern
5.7. Portée de bloc
5.8. Portée de fichier
5.9. Durée de vie automatique, statique et dynamique
5.10. Constantes et immutabilité apparente avec const
Chapitre 6 — Types fondamentaux
6.1. char, short, int, long, long long
6.2. Types signés et non signés
6.3. float, double, long double
6.4. _Bool / bool
6.5. void
6.6. Tailles minimales garanties par la norme
6.7. Types entiers fixes de <stdint.h>
6.8. Types de taille et d’index (size_t, ptrdiff_t)
6.9. Qualificateurs de type
Chapitre 7 — Mémoire, représentation et conversions
7.1. Octets, adresses et objets
7.2. Représentation en mémoire
7.3. Alignement
7.4. sizeof et _Alignof / alignof selon la norme
7.5. Promotions entières
7.6. Conversions implicites
7.7. Casts explicites
7.8. Troncatures, dépassements et pertes de précision
7.9. Lecture correcte des types composés
Chapitre 8 — Opérateurs et expressions
8.1. Opérateurs arithmétiques
8.2. Opérateurs relationnels
8.3. Opérateurs logiques
8.4. Opérateurs d’affectation
8.5. Incrémentation et décrémentation
8.6. Opérateurs binaires et bit à bit
8.7. Priorité et associativité
8.8. Effets de bord
8.9. Ordre d’évaluation et pièges classiques
Chapitre 9 — Contrôle du flux
9.1. if, else, else if
9.2. switch
9.3. for
9.4. while
9.5. do ... while
9.6. break
9.7. continue
9.8. goto
9.9. Retour anticipé
9.10. Structurer un flux lisible
Chapitre 10 — Fonctions
10.1. Déclaration, définition, prototype
10.2. Paramètres et valeur de retour
10.3. Passage par valeur
10.4. Simulation du passage par référence avec pointeur
10.5. Récursion
10.6. Fonctions static
10.7. Fonctions variadiques
10.8. Organisation des API en C
Chapitre 11 — Tableaux
11.1. Déclaration de tableaux
11.2. Initialisation
11.3. Parcours
11.4. Tableaux multidimensionnels
11.5. Taille logique vs taille mémoire
11.6. Décroissance tableau → pointeur
11.7. Passage d’un tableau à une fonction
11.8. Erreurs fréquentes sur les bornes
Chapitre 12 — Chaînes de caractères
12.1. char[] et terminaison \0
12.2. Littéraux de chaîne
12.3. Différence entre tableau et pointeur sur chaîne
12.4. Longueur, copie, concaténation
12.5. Comparaison
12.6. Fonctions utiles de <string.h>
12.7. Limites des fonctions non bornées
12.8. Manipulation robuste des buffers texte
Chapitre 13 — Pointeurs
13.1. Adresse d’un objet
13.2. Déclaration de pointeurs
13.3. Déréférencement
13.4. Pointeur nul
13.5. Pointeurs et tableaux
13.6. Arithmétique des pointeurs
13.7. Pointeur vers pointeur
13.8. const avec les pointeurs
13.9. Pièges classiques
Chapitre 14 — Allocation dynamique
14.1. Mémoire automatique vs dynamique
14.2. malloc
14.3. calloc
14.4. realloc
14.5. free
14.6. Vérification des erreurs
14.7. Fuites mémoire
14.8. Double libération
14.9. Pointeurs pendants
14.10. Stratégies de gestion mémoire
Chapitre 15 — Structures, unions et énumérations
15.1. struct
15.2. Accès aux champs
15.3. Structures imbriquées
15.4. Tableaux de structures
15.5. Pointeurs vers structures
15.6. union
15.7. Cas d’usage des unions
15.8. enum
15.9. Représentation et limites
15.10. typedef et lisibilité
Chapitre 16 — Préprocesseur
16.1. #include
16.2. #define objet
16.3. Macros avec paramètres
16.4. Parenthésage et pièges
16.5. Compilation conditionnelle
16.6. Include guards
16.7. #if, #ifdef, #ifndef, #elif, #endif
16.8. Macros de compilation courantes
16.9. Quand éviter les macros
Chapitre 17 — Bibliothèque standard C : vue d’ensemble
17.1. Rôle de la libc
17.2. Ce qui relève du langage et ce qui relève de la bibliothèque
17.3. En-têtes standards
17.4. Fonctions, macros, types et constantes
17.5. Limites de la bibliothèque standard
17.6. Différences entre implémentations de libc
17.7. Hosted vs freestanding pour la bibliothèque
Chapitre 18 — La libc en pratique, partie 1 : entrées/sorties
18.1. <stdio.h>
18.2. printf, fprintf, snprintf
18.3. scanf et ses limites
18.4. Flux stdin, stdout, stderr
18.5. Tamponnement
18.6. Lecture ligne par ligne
18.7. Gestion des erreurs d’E/S
Chapitre 19 — La libc en pratique, partie 2 : chaînes, mémoire, utilitaires
19.1. <string.h>
19.2. <stdlib.h>
19.3. <ctype.h>
19.4. <math.h>
19.5. <time.h>
19.6. <errno.h>
19.7. <assert.h>
19.8. <limits.h> et <float.h>
19.9. <stdint.h> et <inttypes.h>
Chapitre 20 — Modularité et organisation d’un projet
20.1. Séparer interface et implémentation
20.2. Concevoir un bon fichier d’en-tête
20.3. Déclarations publiques et privées
20.4. static de fichier
20.5. extern
20.6. API interne vs API externe
20.7. Arborescence d’un projet C
20.8. Convention de nommage
20.9. Documentation technique minimale
Chapitre 21 — Types de projets en C
21.1. Programme exécutable
21.2. Bibliothèque statique
21.3. Bibliothèque dynamique / partagée
21.4. Outil en ligne de commande
21.5. Service système
21.6. Bibliothèque embarquée
21.7. Plugin
21.8. Tests et utilitaires internes
21.9. Choisir le bon type de livrable
Chapitre 22 — Édition de liens, ABI et binaire
22.1. Qu’est-ce que le linking
22.2. Symboles
22.3. Résolution des références externes
22.4. Bibliothèques statiques et dynamiques
22.5. Nom mangling et compatibilité C
22.6. ABI : définition et enjeux
22.7. Convention d’appel
22.8. Alignement, padding et compatibilité binaire
22.9. Stabilité d’ABI
22.10. Inspection d’un binaire
Chapitre 23 — Interopérabilité et FFI
23.1. Qu’est-ce que la FFI
23.2. Exposer une API C propre
23.3. Consommer une bibliothèque écrite en C
23.4. Compatibilité avec d’autres langages
23.5. Contraintes de structure mémoire
23.6. Gestion des erreurs à la frontière FFI
23.7. API stable et versionnement
23.8. Bonnes pratiques d’interface
Chapitre 24 — Partie système : principes généraux
24.1. Ce que le langage C standard ne couvre pas
24.2. Appels système et API système
24.3. POSIX : idée générale
24.4. Différences POSIX / Windows
24.5. Processus et environnement d’exécution
24.6. Variables d’environnement
24.7. Répertoires et chemins
24.8. Horloge, temps, dates
24.9. Signaux : introduction
24.10. Limites de la portabilité système
Chapitre 25 — Fichiers, répertoires et système de fichiers
25.1. Fichiers texte et binaires
25.2. Chemins relatifs et absolus
25.3. Métadonnées
25.4. Répertoires
25.5. Permissions
25.6. Opérations courantes sur les fichiers
25.7. Portabilité des chemins
25.8. Encodages et fin de ligne
25.9. Accès bas niveau vs libc
Chapitre 26 — Processus et exécution
26.1. Processus et programme
26.2. Arguments de la ligne de commande
26.3. Code de retour
26.4. Lancer un autre programme
26.5. Attendre un processus fils
26.6. Redirections
26.7. Communication simple entre processus
26.8. Particularités multi-plateformes
Chapitre 27 — Threads et concurrence
27.1. Notions de concurrence et de parallélisme
27.2. Données partagées
27.3. Conditions de course
27.4. Threads C11
27.5. Threads POSIX
27.6. Mutex
27.7. Variables de condition
27.8. Atomiques C11
27.9. Visibilité mémoire
27.10. Concevoir du code thread-safe
Chapitre 28 — Réseau en C
28.1. Ce que signifie programmer le réseau
28.2. Sockets
28.3. IPv4 et IPv6
28.4. TCP et UDP
28.5. Résolution de noms
28.6. Serveur simple
28.7. Client simple
28.8. Blocant vs non bloquant
28.9. Portabilité réseau
28.10. Gestion correcte des erreurs réseau
Chapitre 29 — Gestion des erreurs
29.1. Codes de retour
29.2. errno
29.3. perror et strerror
29.4. Stratégies d’erreur en bibliothèque
29.5. Nettoyage en cas d’échec
29.6. Contrats et préconditions
29.7. Assertions et vérifications
29.8. Erreurs récupérables et fatales
Chapitre 30 — Undefined Behavior, comportements indéfinis et pièges
30.1. Définition de l’UB
30.2. Unspecified behavior
30.3. Implementation-defined behavior
30.4. Exemples classiques d’UB
30.5. Dépassements, aliasing, accès hors limites
30.6. Ordre d’évaluation
30.7. Pointeurs invalides
30.8. Pourquoi le compilateur peut “casser” votre intuition
30.9. Méthodes pour éviter ces erreurs
Chapitre 31 — Débogage, analyse et qualité
31.1. Compiler avec les bons warnings
31.2. Niveau d’optimisation et debug
31.3. gdb / lldb : notions utiles
31.4. Sanitizers
31.5. Analyse statique
31.6. Outils mémoire
31.7. Traces et logs
31.8. Reproduire un bug
31.9. Vérifier un comportement suspect
Chapitre 32 — Build systems et automatisation
32.1. Compilation manuelle
32.2. make
32.3. Structure d’un Makefile
32.4. Variables, règles, dépendances
32.5. Builds debug et release
32.6. cmake
32.7. Génération multi-plateforme
32.8. Autres outils de build
32.9. Organisation d’un pipeline de build
Chapitre 33 — Tests
33.1. Pourquoi tester en C
33.2. Tests unitaires
33.3. Tests d’intégration
33.4. Programmes de test maison
33.5. Frameworks de test
33.6. Fichiers de données de test
33.7. Couverture de code
33.8. Régression et automatisation
Chapitre 34 — Packaging et distribution
34.1. Distribuer un exécutable
34.2. Distribuer une bibliothèque
34.3. Gestion des dépendances
34.4. Distribution Linux
34.5. Distribution Windows
34.6. Distribution macOS
34.7. Packaging cross-platform
34.8. Installeurs, archives, paquets
34.9. Versionnement
34.10. Compatibilité et support
Chapitre 35 — Sécurité, sûreté et standards industriels
35.1. Sécurité mémoire en C
35.2. Surfaces d’attaque classiques
35.3. Entrées non fiables
35.4. CERT C
35.5. MISRA C
35.6. Contexte embarqué et critique
35.7. Déviations documentées
35.8. Revue de code et exigences qualité
35.9. Écrire du C plus sûr sans changer de langage
Chapitre 36 — Bonnes pratiques de style et conception
36.1. Lisibilité
36.2. Simplicité
36.3. Interfaces claires
36.4. Cohérence de nommage
36.5. Réduction du couplage
36.6. Limitation des effets de bord
36.7. Documentation utile
36.8. Conception défensive
36.9. Maintenabilité long terme
Chapitre 37 — Projet final complet
37.1. Choix du sujet
37.2. Spécification
37.3. Architecture
37.4. Modules et fichiers
37.5. Build
37.6. Tests
37.7. Packaging
37.8. Distribution
37.9. Améliorations possibles
Chapitre 38 — Annexes
38.1. Glossaire
38.2. Tableau récapitulatif des types
38.3. Tableau récapitulatif de la libc
38.4. Tableau des normes C
38.5. Rappels sur la compilation
38.6. Checklist de portabilité
38.7. Checklist de sécurité
38.8. Mini aide-mémoire des commandes utiles