IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Bien programmer en langage C

Date de publication : 28 mai 2008

Par Emmanuel Delahaye
 

Le langage C, bien qu'ancien, est toujours d'actualité, notamment dans le domaine du logiciel embarqué. Il est réputé pour sa puissance et son efficacité. Il dispose d'une syntaxe qui allie une certaine proximité avec la machine (mais en restant portable) et un bon niveau d'abstraction.
Son apparente simplicité cache certaines difficultés d'utilisation qu'il est bon de mettre en évidence afin d'éviter des erreurs de réalisation.
Petit florilège : L'Echelle de Goret.
Le but de ce site est de fournir au programmeur les moyens de réaliser du code correct, fiable et maintenable. Il s'adresse autant aux débutants qu'aux programmeurs C avertis.
En plus de l'étude de certains phénomènes dangereux du langage, et des moyens de les éviter, ce site fourni des conseils sur l'organisation du développement d'un projet en C, ainsi qu'une bibliothèque de fonctions écrites en C standard (ISO/IEC 9899:1990 ou C90) permettant de réaliser des opérations courantes de façon fiable et simple.

Ressources
Internet
Pour compléter les éléments apportés par ce site, je ne saurais trop recommander la consultation des deux FAQ C dont celle de Steve Summit en anglais et celle de Guillaume Rumeau en français. Ce sont des mines d'informations qu'il convient de lire et de relire régulièrement.
Je recommande aussi la fréquentation des deux forums USENET qui sont à l'origine de ces FAQ, soit news:comp.lang.c et news:fr.comp.lang.c ne serait-ce qu'en lecture simple. Il est bien sûr conseillé d'y poser des questions si celles-ci n'ont pas trouvé de réponses dans leurs FAQ respectives. Il existe aussi un CLC-Wiki qui centralise petit à petit les informations pertinentes de c.l.c.
Je signale aussi l'existence du forum privé Développez qui contient aussi beaucoup d'informations de bases sur le C et les autres langages de programmation.
Enfin, vous trouverez une référence détaillée et très lisible (en anglais) des fonctions de la bibliothèque standard C90 ou C99
J'ajoute un document de référence non officiel mais très détaillé qui explique la norme (ISO) avec précision (en anglais) : Le rationale.
Spécial étudiant fauché. Voici un bon livre de C gratuit en anglais The C Book avec exercices et corrigés, sans oublier le tutoriel en français de Bernard Cassagne, et le cours avancé d'Anne Canteaut.
Enfin, pour les spécialistes à la recherche de structures de données plus ou moins complexes, je signale l'existence de la Kazlib. (en anglais).
Autre référence de haut niveau, le site de Chris Torek (un éminent intervenant de comp.lang.c. Toutes ses réponses sont bonnes à lire).
Je signale aussi l'existence du Site du Zéro qui, malgré sa présentation jeune et ludique, bénéficie d'un contenu rédactionnel correct[1]. A recommander pour les moins de 18 ans... (et même les autres, après tout). Les cours sont prolongés par un forum C tout à fait convenable.
Littérature
La référence incontournable : Le livre de Brian Kernighan et Dennis Ritchie, les fondateurs : Le langage C à compléter de l' errata
Autre livre intéressant, qui traite, entre autre, de C99 : Méthodologie de la programmation en C écrit par Achille Braquelaire.
Les apprentis gourous trouveront dans ce livre C-Unleashed. (en anglais) des techniques de développement C très pointues et très portables. Ecrit par de nombreux intervenants de haut niveau de comp.lang.c. "Le livre de la communauté C".

[1] bien que je ne sois pas d'accord avec certains choix de l'auteur, comme l'usage de scanf() ou des long.

   

 

Initiation
I. Initiation pragmatique au langage C
I-A. Introduction
I-B. Programme minimum
I-B-1. Analyse détaillée
I-C. Un programme qui dit "bonjour"
I-D. Glossaire
I-D-1. Byte
I-D-2. Caractère
I-D-3. Chaine de caractères
I-D-4. Comportement indéfini
I-D-5. Fonction
I-D-6. Flux
I-D-7. Paramètre
I-D-8. Préprocesseur
I-D-9. Prototype
I-D-10. sizeof
I-D-11. Tableau
I-D-12. Type
Les bases
II. Codage en langage C
II-A. Conventions de nommage
II-A-1. Constantes
II-A-1-a. Types
II-A-1-b. Conventions typographiques
II-A-1-c. Objets (Variables)
II-A-1-c-i. Conventions typographiques
II-A-1-c-ii. Identificateur
II-A-1-d. Fonctions
II-A-1-d-i. Conventions typographiques
II-A-1-d-ii. Identificateur
II-B. Organisation du code source
II-B-1. Fichiers sources (*.c)
II-B-1-a. Liste ordonnée des éléments pouvant être contenus dans un fichier source
II-B-2. Fichiers d'en-tête (*.h)
II-B-2-a. Règles d'or régissant la définition des fichiers d'en-tête
II-B-2-b. Liste ordonnée des éléments pouvant être contenus dans un fichier d'en-tête
II-B-2-c. Protection contre les inclusions multiples
II-C. Comment bien organiser son développement.
II-D. Comment construire sa bibliotheque.
II-D-1. Outil de développement gcc
II-D-1-a. Création d'une bibliothèque sous Code::Blocks
II-E. Comment bien configurer son compilateur.
II-E-1. gcc
II-E-2. Reglages dans Code::Blocks
II-E-3. Reglages dans wxDev-C++ (remplace Dev-C++ devenu obsolète)
II-E-4. Microsoft Visual C++ (6, 2005, 2008 etc.)
II-E-5. Borland C / Turbo C
Bibliothèque
III. Bibliothèque C:CLIB
Notes
IV. Notes
IV-A. Saisie de données par un opérateur (stdin)
IV-A-1. Introduction
IV-A-2. fgetc(), getc(), getchar()
IV-A-3. gets()
IV-A-4. scanf()
IV-A-5. fgets()
IV-A-6. Ressources
IV-A-7. Comment fonctionne fgetc(stdin) alias getchar()
IV-A-7-a. Comportement visible.
IV-A-7-b. Comportement interne.
IV-A-7-c. Quelques expérimentations.
IV-B. Les pointeurs démythifiés !
IV-B-1. Introduction
IV-B-2. Définition
IV-B-2-a. Pointeur sur objet
IV-B-2-b. Pointeur de fonction
IV-B-2-b-i. Remarques importantes
IV-C. Du bon usage des pointeurs
IV-D. Passer un tableau à une fonction
IV-D-1. Introduction
IV-D-2. Tableau à une dimension
IV-D-3. Tableau à n dimensions
IV-E. char* char**
IV-E-1. Introduction
IV-E-2. Chaine de caractères
IV-E-3. Le type char *
IV-E-4. Le type char **
IV-F. Les fichiers
IV-F-1. Introduction
IV-F-2. Texte ou binaire ?
IV-F-2-a. Fichier texte
IV-F-2-b. Fichier binaire
IV-F-2-c. Modes d'ouverture d'un fichier
IV-F-2-d. Lecture d'un fichier
IV-F-2-d-i. fgetc(), getc()
IV-F-2-d-ii. fread()
IV-F-2-d-iii. fscanf()
IV-F-2-d-iv. fgets()
IV-F-2-d-iv--1. Exemple d'utilisation
IV-F-2-d-iv--2. Explication
IV-F-2-d-iv--3. Critique de cet exemple
IV-F-2-d-iv--4. Détection d'une erreur
IV-F-2-d-iv--5. Gestion des fins de ligne
IV-F-2-d-iv--6. Exemple amélioré avec détection de la fin de lecture
IV-F-2-d-iv--7. Explication
IV-F-2-e. Écriture dans un fichier
IV-F-2-e-i. fputc(), putc()
IV-F-2-e-ii. fwrite()
IV-F-2-e-iii. fprintf()
IV-F-2-e-iv. fputs()
IV-F-2-f. Bien utiliser les formats de données
IV-F-2-f-i. Format orienté texte
IV-F-2-f-ii. Format orienté binaire
IV-F-3. Supprimer un enregistrement dans un fichier binaire
IV-F-4. En guise de conclusion
IV-G. Se procurer la norme du langage C (C99)
IV-H. Bien utiliser malloc()
IV-H-1. Suppression du cast
IV-H-1-a. Compilateur non ISO
IV-H-1-b. Compilateur C++
IV-H-2. Déterminer la taille sans le type
IV-I. Bien utiliser realloc()
IV-J. Borland C : "floating point formats not linked"
IV-K. Production du code exécutable
IV-L. Bibliothèques de fonctions
IV-L-1. Bibliothèque statique
IV-L-2. Bibliothèque dynamique
IV-M. Variables globales
IV-M-1. Nommage
IV-M-2. Organisation
IV-M-3. Définition
IV-M-4. Déclaration
IV-M-5. Utilisation
IV-N. Champs de bits
IV-O. Le type retourné par main()
IV-0-1. Historique
IV-P. Pourquoi fflush (stdout) ?
IV-Q. Bien gérer la portée des objets et des fonctions
IV-Q-1. Fonctions
IV-Q-2. Objets
IV-Q-2-a. Définition hors d'un bloc
IV-Q-2-b. Définition dans un bloc
IV-Q-2-c. Masquage (Shadowing)
IV-R. <time.h> : bien utiliser difftime()
IV-S. C, UNIX, POSIX ?
IV-T. Initialisation des tableaux de caractères
IV-U. Déclarations ? Définitions ?
IV-U-1. Déclaration
IV-U-2. Définition
IV-V. Données
IV-V-1. Initialisation
IV-W. Le mode plein ecran
IV-W-1. Installation de ansi.sys sous Windows XP
IV-X. Les identificateurs réservés
IV-Y. Code standard ? Code portable ? Je suis perdu !
IV-Y-1. "standard" ?
IV-Y-2. "portable" ?
IV-Y-2-a. portabilité absolue
IV-Y-2-b. portabilité relative
IV-Y-3. Bon usage
IV-Z. Langage C ? Fonctions systemes ? Je suis perdu !
IV-Z-1. Domaine couvert par le langage C
IV-Z-2. Fonctions système
IV-Z-3. Bibliothèques tierces publiques
IV-Z-4. Bibliothèques tierces privées
IV-AA. size_t, c'est quoi ?
IV-AB. Un tableau n'est pas un pointeur ! Vrai ou faux ?
IV-AC. Du bon usage de assert()
IV-AC-1. Exemple d'utilisation
IV-AD. rand(), srand()... j'y comprends rien...
IV-AE. C'est quoi un prototype ?
IV-AF. C'est quoi l'algorithmique ?
IV-AG. pile, tas ? C'est quoi ?
IV-AH. Les pointeurs, ça sert à quoi ?
LIV-AH-1. A quoi ça sert?
IV-AH-1-a. Petit rappel.
IV-AH-1-b. Comment faire ?
IV-AI. Qu'est-ce qu'une chaine litterale ?
IV-AJ. Enregister une structure
IV-AJ-1. Le format binaire
IV-AJ-2. Le format texte
IV-AK. Retourner un tableau
IV-AL. Comportement indéfini
IV-AM. C'est quoi ce 'static' ?
IV-AN. Pourquoi ma fonction ne modifie pas ma variable ?
IV-AO. Comment créer un tableau dynamique à 2 dimensions ?
IV-AP. Bien utiliser const
IV-AP-1. Objets simples
IV-AP-2. Pointeurs
IV-AP-3. Usage
IV-AQ. Structures
IV-AQ-1. Structures visibles
IV-AQ-2. Structures opaques
IV-AQ-3. Pseudonymes (ou alias)
Conception et réalisation en C
V. Concevoir et réaliser un composant logiciel en C
V-A. Introduction
V-B. Stratégie de développement d'un composant logiciel
V-B-1. Modélisation d'un composant logiciel
V-B-2. Implémentation du modèle.
V-C. Etude de cas : Un gestionnaire d'alarme à niveaux
V-C-1. Spécifications
V-C-2. Conception
V-C-3. Réalisation en C
V-C-3-a. Nommage du composant logiciel
V-C-3-b. Interface
V-C-3-c. Implémentation
Types abstraits de données
VI. Les types abstraits de données (ADT)
VI-A. Introduction
VI-B. Analyse de l'objet standard FILE
VI-C. Définition du type abstrait de donnée
VI-D. Implémentation du type abstrait de donnée en C
VI-D-1. Constructeur
VI-D-2. Destructeur
VI-D-3. Fichier d'interface
VI-D-4. Utilisation
VI-E. Exemple réel d'ADT
VI-E-1. Spécification
VI-E-2. Conception
VI-E-2-a. Nommage
VI-E-2-b. Fonctions
VI-E-2-c. Interfaces détaillées
VI-E-3. Réalisation en langage C
VI-E-3-a. Fichier d'interface
VI-E-3-a-i. Note de codage
VI-E-3-b. Fichier d'implémentation
VI-E-3-c. Remarque
VI-E-4. Tests unitaires
Réseaux
VII. Notes brutes concernant les réseaux
VII-A. Ouvrages de références
VII-B. Dialogue Terminal Modem
VII-C. Réalisation d'un projet réseau
VII-C-1. Sockets
VII-C-1-a. Introduction
VII-C-1-b. Protocoles
VII-C-1-c. Fonctions
VII-C-1-d. Serveur
VII-C-1-e. Client
VII-C-2. Réalisation d'un Client / Serveur UDP/IP
VII-C-2-a. Serveur UDP/IP
VII-C-2-b. Client UDP/IP
VII-C-3. Réalisation d'un Client / Serveur TCP/IP
VII-C-3-a. Serveur TCP/IP
VII-C-3-b. Client TCP/IP
VII-C-3-c. Serveur multiclient en TCP/IP
VII-D. Réalisation pas à pas d'un serveur TCP/IP
VII-D-1. Introduction
VII-D-1-a. Avertissement
VII-D-1-b. Environnement de développement
VII-D-1-c. Environnement de test
VII-D-2. 01 - Initialisation, terminaison
VII-D-3. 02 - Création, suppression de sockets
VII-D-4. 03 - Mini serveur : Mise en écoute du port 23
VII-D-5. 04 - Mini serveur : Connexion du client/ Déconnexion du client
VII-D-6. 05 - Reception d'un caractère puis fermeture
VII-D-7. 06 - Mini serveur : Reception d'un bloc de données puis fermeture sur ESC
VII-D-7-a. Pseudo-code
VII-D-7-b. Code
VII-D-8. 07 - Mini serveur : Reception d'un bloc de données puis deconnexion sur ESC
VII-D-8-a. Pseudo-code
VII-D-8-b. Code
VII-D-9. 08 - Serveur-multi-clients : Reception d'un bloc de données puis deconnexion sur ESC
VII-D-9-a. Pseudo-code
VII-D-9-b. Code
VII-D-10. Conclusion
VII-E. Transmettre du texte par sockets
VII-E-1. Emission de petits blocs (cas simple)
VII-E-2. Reception de petits blocs
VII-E-3. Emission de gros blocs (cas général)
VII-E-4. Réception de gros blocs
VII-F. Etude de cas : transmettre un fichier texte.
VII-F-1. Spécifications
VII-F-2. Conception
VII-F-2-a. Protocole
VII-F-2-a-i. Format des messages
VII-F-2-a-ii. Commandes
VII-F-2-a-iii. Réponses
VII-F-2-a-iv. Exemple de dialogue
VII-G. Du bon usage de select()
VII-G-1. Introduction
VII-G-2. Programmation
VII-G-3. Exemples d'utilisation
VII-G-3-a. Suspension temporisée
VII-G-3-b. Surveillance d'un flux en réception
VII-G-3-c. Surveillance de deux flux en réception
VII-G-4. Conclusion
VII-H. La récupération de l'IP à partir du nom du serveur
VII-I. Ebauche d'une bibliothèque sockets portable (psock)
VII-I-1. Interfaces communes
VII-I-2. Sockets UNix (sun)
VII-I-3. Sockets IP (Internet Protocol)
VII-J. Ressources
MAKE
VIII. L'outil MAKE
VIII-A. Introduction
VIII-B. Principes
VIII-C. Exemple de base
VIII-D. Ajout de cibles
VIII-E. Utilisation des variables
VIII-E-1. Définition d'une variable
VIII-E-2. Utilisation d'une variable
VIII-E-3. Amélioration de l'exemple
VIII-F. Variables automatiques
Les threads POSIX
IX. POSIX threads
IX-A. Systèmes multi-tâches
IX-A-1. Introduction
IX-A-2. Processus
IX-A-2-a. Exécution
IX-A-2-b. Création dynamique de processus
IX-A-3. Processus légers
IX-B. Introduction
IX-B-1. Note pour Windows.
IX-B-2. Objectif
IX-C. Hello worlds
IX-D. Données
IX-D-1. Éviter les globales 'à-la-barbare'
IX-D-2. Le cas de l'écrivain et du lecteur
IX-E. Synchronisation
IX-F. Résumé des types et des fonctions utilisés
IX-G. Ressources
Les listes chaînées
X. Les listes chaînées
X-A. Introduction
X-B. Implémentation d'une liste chaînée simple
X-B-1. Implémentation avec structure.
Entrées solides en C
XI. Entrées solides en C
XI-A. Introduction
XI-B. Les fonctions d'entrées standards
XI-C. Mise en évidence du fonctionnement de fgetc()
XI-D. Réalisation d'une fonction de lecture de lignes()
XI-D-1. Stocker les données reçues.
XI-D-2. Créer une fonction de saisie
XI-D-2-a. Définition générale
XI-D-2-b. Définition de l'interface
XI-D-2-c. Définition du comportement.
XI-D-2-d. Conception
XI-D-2-e. Codage et tests unitaires
XI-D-2-e-i. Interface, contrôle des paramètres
XI-D-2-e-ii. Boucle de saisie, stockage
XI-D-2-e-iii. Finalisation. Constantes pour les erreurs, traitement du <EOF>, compilation séparée.
XI-E. Conclusion
Développement de projet informatique
XII. Développement de projet informatique
XII-A. Introduction au développement d'un projet informatique
XII-B. Un peu de reflexion et du bon sens
XII-C. Le cycle en V
XII-C-1. Le document de définition
XII-C-2. Le document de conception
XII-C-3. Les fichiers sources et les tests unitaires
XII-C-4. Le cahier de test d'intégration
XII-C-5. Le document de validation
XII-C-6. Pourquoi en V ?
XII-D. Critique de la méthode du cycle en V
XII-E. Les méthodes dites 'agiles'
XII-E-1. Introduction
XII-E-1-a. Les itérations courtes
XII-E-1-b. La conception par les tests
XII-E-1-c. La réécriture
XII-E-1-d. Le travail en binôme
XII-E-1-e. Le travail en équipe
Etude de cas : Un 'snake' portable en mode console
XIII. Etude de cas : Un 'snake' portable en mode console
XIII-A. Introduction
Opérateurs bit à bit
XIV. Opérateurs bit à bit
XIV-A. Description des opérateurs bits à bits
XIV-A-1. Introduction
XIV-A-2. NOT (NON)
XIV-A-3. AND (ET)
XIV-A-4. OR (OU)
XIV-A-5. XOR (OU exclusif)
XIV-A-6. SHR (Décalage à droite)
XIV-A-7. SHL (Décalage à gauche)
XIV-B. Usages des opérateurs bits à bits
XIV-B-1. Manipulations de l'état des bits d'une variable
XIV-B-1-a. Positionner un bit à 1
XIV-B-1-b. Positionner un bit à 0
XIV-B-1-c. Tester la valeur d'un bit
XIV-B-2. Conclusion



   

 

Valid XHTML 1.1!Valid CSS!

Copyright © 2008 Emmanuel Delahaye. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.