Le guide complet du langage C
Claude Delannoy
Eyrolles
Avant-propos1
À qui s'adresse ce livre ?
1
Structure de l'ouvrage
2
À propos des normes ANSI/ISO
4
À propos de la fonction main
4
Remerciements
5
Chapitre 1
Généralités
1. Historique du langage C
7
2. Programme source, module objet et programme exécutable
8
3. Compilation en C : existence d'un préprocesseur
9
4. Variable et objet
10
4.1 Définition d'une variable et d'un objet10
4.2 Utilisation d'un objet10
5. Lien entre objet, octets et caractères
12
6. Classe d'allocation des variables
12
Chapitre 2
Les éléments constitutifs d'un programme source15
1. Jeu de caractères source et jeu de caractères d'exécution
16
1.1 Généralités16
1.2 Commentaires à propos du jeu de caractères source17
1.3 Commentaires à propos du jeu minimal de caractères d'exécution18
2. Les identificateurs
19
3. Les mots-clés
20
4. Les séparateurs et les espaces blancs
20
5. Le format libre
21
6. Les commentaires
22
7. Notion de token
23
7.1 Les différentes catégories de tokens23
7.2 Décomposition en tokens25
Chapitre 3
Les types de base27
1. Les types entiers
27
1.1 Les six types entiers28
1.2 Représentation mémoire des entiers et limitations29
1.3 Critères de choix d'un type entier32
1.4 Écriture des constantes entières33
1.5 Le type attribué par le compilateur aux constantes entières34
1.6 Exemple d'utilisation déraisonnable de constantes hexadécimales35
1.7 Pour imposer un type aux constantes entières36
1.8 En cas de dépassement de capacité dans l'écriture des constantes entières36
2. Les types caractère
37
2.1 Les deux types caractère37
2.2 Caractéristiques des types caractère38
2.3 Écriture des constantes caractère40
2.4 Le type des constantes caractère43
3. Le fichier limits.h
45
3.1 Son contenu45
3.2 Précautions d'utilisation46
4. Les types flottants
46
4.1 Rappels concernant le codage des nombres en flottant46
4.2 Le modèle proposé par la norme47
4.3 Les caractéristiques du codage en flottant48
4.4 Représentation mémoire et limitations50
4.5 Écriture des constantes flottantes51
4.6 Le type des constantes flottantes52
4.7 En cas de dépassement de capacité dans l'écriture des constantes52
5. Le fichier float.h
53
6. Déclarations des variables d'un type de base
54
6.1 Rôle d'une déclaration55
6.2 Initialisation lors de la déclaration56
6.3 Les qualifieurs const et volatile57
Chapitre 4
Les opérateurs et les expressions61
1. Généralités
62
1.1 Les particularités des opérateurs et des expressions en C62
1.2 Priorité et associativité63
1.3 Pluralité64
1.4 Conversions implicites64
1.5 Les différentes catégories d'opérateurs65
2. Les opérateurs arithmétiques
65
2.1 Les différents opérateurs numériques66
2.2 Comportement en cas d'exception69
3. Les conversions numériques implicites
74
3.1 Introduction74
3.2 Les conversions numériques d'ajustement de type75
3.3 Les promotions numériques80
3.4 Combinaisons de conversions86
3.5 Cas particulier des arguments d'une fonction88
4. Les opérateurs relationnels
89
4.1 Généralités89
4.2 Les six opérateurs relationnels du langage C90
4.3 Leur priorité et leur associativité91
5. Les opérateurs logiques
93
5.1 Généralités93
5.2 Les trois opérateurs logiques du langage C94
5.3 Leur priorité et leur associativité95
5.4 Les opérandes de (...) et de II ne sont évalués que si nécessaire96
6. Les opérateurs de manipulation de bits
97
6.1 Présentation des opérateurs de manipulation de bits97
6.2 Les opérateurs « bit à bit »98
6.3 Les opérateurs de décalage100
6.4 Applications usuelles des opérateurs de manipulation de bits102
7. Les opérateurs d'affectation et d'incrémentation
104
7.1 Généralités104
7.2 La lvalue105
7.3 L'opérateur d'affectation simple106
7.4 Tableau récapitulatif : l'opérateur d'affectation simple108
7.5 Les opérateurs d'affectation élargie109
8. Les opérateurs de cast
110
8.1 Généralités110
8.2 Les opérateurs de cast111
9. Le rôle des conversions numériques
113
9.1 Conversion d'un type flottant vers un autre type flottant113
9.2 Conversion d'un type flottant vers un type entier114
9.3 Conversion d'un type entier vers un type flottant114
9.4 Conversion d'un type entier vers un autre type entier115
9.5 Cas particuliers des conversions d'entier vers caractère116
9.6 Tableau récapitulatif des conversions numériques118
10. L'opérateur conditionnel
119
10.1 Introduction119
10.2 Rôle de l'opérateur conditionnel120
10.3 Contraintes et conversions120
10.4 La priorité de l'opérateur conditionnel122
11. L'opérateur séquentiel
122
12. L'opérateur sizeof
124
12.1 L'opérateur sizeof appliqué à un nom de type124
12.2 L'opérateur sizeof appliqué à une expression125
13. Tableau récapitulatif : priorités et associativité des opérateurs
127
14. Les expressions constantes
128
14.1 Introduction128
14.2 Les expressions constantes d'une manière générale129
Chapitre 5
Les instructions exécutables133
1. Généralités
133
1.1 Rappels sur les instructions de contrôle134
1.2 Classification des instructions exécutables du langage C134
2. L'instruction expression
136
2.1 Syntaxe et rôle136
2.2 Commentaires136
3. L'instruction composée ou bloc
137
3.1 Syntaxe d'un bloc137
3.2 Commentaires138
3.3 Déclarations dans un bloc139
3.4 Cas des branchements à l'intérieur d'un bloc140
4. L'instruction if
140
4.1 Syntaxe et rôle de l'instruction if140
4.2 Exemples d'utilisation141
4.3 Cas des if imbriqués144
4.4 Traduction de choix en cascade145
5. L'instruction switch
147
5.1 Exemple introductif147
5.2 Syntaxe usuelle et rôle de switch148
5.3 Commentaires149
5.4 Quelques curiosités de l'instruction switch150
6. Choix entre if et switch
152
7. Les particularités des boucles en C
153
7.1 Rappels concernant la programmation structurée153
7.2 Les boucles en C154
8. L'instruction do ... while
155
8.1 Syntaxe155
8.2 Rôle155
8.3 Exemples d'utilisation157
9. L'instruction while
158
9.1 Syntaxe159
9.2 Rôle159
9.3 Lien entre while et do ... while160
9.4 Exemples d'utilisation161
10. L'instruction for
162
10.1 Introduction162
10.2 Syntaxe163
10.3 Rôle163
10.4 Lien entre for et while164
10.5 Commentaires165
10.6 Exemples d'utilisation166
11. Conseils d'utilisation des différents types de boucles
168
11.1 Boucle définie168
11.2 Boucle indéfinie169
12. L'instruction break
170
12.1 Syntaxe et rôle170
12.2 Exemple d'utilisation170
12.3 Commentaires171
13. L'instruction continue
172
13.1 Syntaxe et rôle172
13.2 Exemples d'utilisation172
13.3 Commentaires173
14. Quelques schémas de boucles utiles
175
14.1 Boucle à sortie intermédiaire175
14.2 Boucles à sorties multiples178
15. L'instruction goto et les étiquettes
179
15.1 Les étiquettes179
15.2 Syntaxe et rôle180
15.3 Exemples et commentaires181
Chapitre 6
Les tableaux185
1. Exemple introductif d'utilisation d'un tableau
186
2. Déclaration des tableaux
187
2.1 Généralités187
2.2 Le type des éléments d'un tableau188
2.3 Déclarateur de tableau188
2.4 La dimension d'un tableau190
2.5 Classe de mémorisation associée à la déclaration d'un tableau192
2.6 Les qualifieurs const et volatile193
2.7 Nom de type correspondant à un tableau194
3. Utilisation d'un tableau
195
3.1 Les indices195
3.2 Un identificateur de tableau n'est pas une Ivalue196
3.3 Utilisation d'un élément d'un tableau196
3.4 L'opérateur sizeof et les tableaux197
4. Arrangement d'un tableau et débordement d'indice
198
4.1 Les éléments d'un tableau sont alloués de manière consécutive198
4.2 Aucun contrôle n'est effectué sur la valeur de l'indice199
5. Cas des tableaux de tableaux
200
5.1 Déclaration des tableaux à deux indices200
5.2 Utilisation d'un tableau à deux indices200
5.3 Peut-on parler de lignes et de colonnes d'un tableau à deux indices ?202
5.4 Arrangement en mémoire d'un tableau à deux indices202
5.5 Cas des tableaux à plus de deux indices203
6. Initialisation de tableaux
204
6.1 Initialisation par défaut des tableaux205
6.2 Initialisation explicite des tableaux205
Chapitre 7
Les pointeurs211
1. Introduction à la notion de pointeur
212
1.1 Attribuer une valeur à une variable de type pointeur212
1.2 L'opérateur* pour manipuler un objet pointé213
2. Déclaration des variables de type pointeur
214
2.1 Généralités215
2.2 Le type des objets désignés par un pointeur216
2.3 Déclarateur de pointeur216
2.4 Classe de mémorisation associée à la déclaration d'un pointeur219
2.5 Les qualifieurs const et volatile219
2.6 Nom de type correspondant à un pointeur223
3. Les propriétés des pointeurs
224
3.1 Les propriétés arithmétiques des pointeurs225
3.2 Lien entre pointeurs et tableaux226
3.3 Ordre des pointeurs et ordre des adresses232
3.4 Les restrictions imposées à l'arithmétique des pointeurs232
4. Tableaux récapitulatifs : les opérateurs +, -, et, * et []
235
5. Le pointeur Null
237
6. Pointeurs et affectation
239
6.1 Prise en compte des qualifieurs des objets pointés239
6.2 Les autres possibilités d'affectation241
6.3 Tableau récapitulatif242
6.4 Les affectations élargies += et -= et les incrémentations ++ et --242
7. Les pointeurs génériques
243
7.1 Généralités243
7.2 Déclaration du type void*244
7.3 Interdictions propres au type void*244
7.4 Possibilités propres au type void*245
8. Comparaisons de pointeurs
246
8.1 Comparaisons basées sur un ordre247
8.2 Comparaisons d'égalité ou d'inégalité248
8.3 Récapitulatif : les comparaisons dans un contexte pointeur249
9. Conversions de pointeurs par cast
249
9.1 Conversion d'un pointeur et un pointeur d'un autre type250
9.2 Conversions entre entiers et pointeurs252
9.3 Récapitulatif concernant l'opérateur de cast dans un contexte pointeur253
Chapitre 8
Les fonctions255
1. Les fonctions en C
256
1.1 Une seule sorte de module en C : la fonction256
1.2 Fonction et transmission des arguments par valeur258
1.3 Les variables globales258
1.4 Les possibilités de compilation séparée259
2. Exemple introductif de la notion de fonction en langage C
259
3. Définition d'une fonction
261
3.1 Les deux formes de l'en-tête262
3.2 Les arguments apparaissant dans l'en-tête262
3.3 La valeur de retour264
3.4 Classe de mémorisation d'une fonction : extern et static268
3.5 L'instruction return269
4. Déclaration et appel d'une fonction
272
4.1 Déclaration sous forme de prototype273
4.2 Déclaration partielle (déconseillée)274
4.3 Portée d'une déclaration de fonction275
4.4 Redéclaration d'une fonction276
4.5 Une définition de fonction tient lieu de déclaration277
4.6 En cas d'absence de déclaration278
4.7 Utilisation de la déclaration dans la traduction d'un appel278
4.8 En cas de non-concordance entre arguments muets et arguments effectifs281
4.9 Les fichiers en-tête standards282
4.10 Nom de type correspondant à une fonction283
5. Le mécanisme de transmission d'arguments
284
5.1 Cas où la transmission par valeur est satisfaisante284
5.2 Cas où la transmission par valeur n'est plus satisfaisante285
5.3 Comment simuler une transmission par adresse avec des pointeurs287
6. Cas des tableaux transmis en arguments
289
6.1 Règles générales289
6.2 Exemples d'applications294
6.3 Pour qu'une fonction dispose de la dimension d'un tableau296
6.4 Quelques conseils de style à propos des tableaux en argument298
7. Cas particulier des tableaux de tableaux transmis en arguments
299
7.1 Application des règles générales300
7.2 Artifices facilitant la manipulation de tableaux de dimensions variables304
8. Les variables globales
310
8.1 Exemples introductifs d'utilisation de variables globales311
8.2 Les déclarations des variables globales313
8.3 Portée des variables globales319
8.4 Variables globales et édition de liens320
8.5 Les variables globales sont de classe statique321
8.6 Initialisation des variables globales322
9. Les variables locales
324
9.1 La portée des variables locales324
9.2 Classe d'allocation et initialisation des variables locales326
10. Tableau récapitulatif : portée, accès et classe d'allocation des variables
331
11. Pointeurs sur des fonctions
332
11.1 Déclaration d'une variable pointeur sur une fonction333
11.2 Affectation de valeurs à une variable pointeur sur une fonction334
11.3 Appel d'une fonction par le biais d'un pointeur337
11.4 Exemple de paramétrage d'appel de fonctions339
11.5 Transmission de fonction en argument341
11.6 Comparaisons de pointeurs sur des fonctions342
11.7 Conversions par cast de pointeurs sur des fonctions342
Chapitre 9
Les entrées-sorties standards345
1. Caractéristiques générales des entrées-sorties standards
346
1.1 Mode d'interaction avec l'utilisateur346
1.2 Formatage des informations échangées347
1.3 Généralisation aux fichiers de type texte347
2. Présentation générale de printf
348
2.1 Notions de format d'entrée, de code de format et de code de conversion349
2.2 L'appel de printf350
2.3 Les risques d'erreurs dans la rédaction du format352
3. Les principales possibilités de formatage de printf
355
3.1 Le gabarit d'affichage355
3.2 Précision des informations flottantes358
3.3 Justification des informations360
3.4 Gabarit ou précision variable360
3.5 Le code de format g362
3.6 Le drapeau + force la présence d'un signe « plus »365
3.7 Le drapeau espace force la présence d'un espace366
3.8 Le drapeau 0 permet d'afficher des zéros de remplissage366
3.9 Le paramètre de précision permet de limiter l'affichage des chaînes367
3.10 Cas particulier du type unsigned short int : le modificateur h368
4. Description des codes de format des fonctions de la famille printf
369
4.1 Structure générale d'un code de format369
4.2 Le paramètre drapeaux369
4.3 Le paramètre de gabarit370
4.4 Le paramètre de précision372
4.5 Le paramètre modificateur h/I/L373
4.6 Les codes de conversion373
4.7 Les codes utilisables avec un type donné375
5. La fonction putchar
376
5.1 Prototype377
5.2 L'argument de putchar est de type int377
5.3 La valeur de retour de putchar378
6. Présentation générale de scanf
378
6.1 Format de sortie, code de format et code de conversion378
6.2 L'appel de scanf379
6.3 Les risques d'erreurs dans la rédaction du format380
6.4 La fonction scanf utilise un tampon383
6.5 Notion de caractère invalide et d'arrêt prématuré384
6.6 La valeur de retour de scanf385
6.7 Exemples de rencontre de caractères invalides387
7. Les principes possibilités de scanf
389
7.1 La présentation des informations lues en données390
7.2 Limitation du gabarit391
7.3 La fin de ligne joue un rôle ambigu : séparateur ou caractère392
7.4 Lorsque le format impose certains caractères dans les données394
7.5 Attention au faux gabarit du code C394
7.6 Les codes de format de la forme %[...]395
8. Description des codes de format des fonctions de la famille de scanf
397
8.1 Récapitulatif des règles utilisées par ces fonctions397
8.2 Structure générale d'un code de format398
8.3 Les paramètres * et gabarit399
8.4 Le paramètre modificateur h/I/L399
8.5 Les codes de conversion400
8.6 Les codes utilisables avec un type donné402
8.7 Les différences entre les codes de format en entrée et en sortie403
9. La fonction getchar
404
9.1 Prototype et valeur de retour404
9.2 Précautions404
Chapitre 10
Les chaînes de caractères407
1. Règles générales d'écriture des constantes chaîne
408
1.1 Notation des constantes chaîne408
1.2 Concaténation des constantes chaînes adjacentes409
2. Propriétés des constantes chaîne
410
2.1 Conventions de représentation411
2.2 Emplacement mémoire412
2.3 Cas des chaînes identiques413
2.4 Les risques de modification des constantes chaîne413
2.5 Simulation d'un tableau de constantes chaîne415
3. Créer, utiliser ou modifier une chaîne
416
3.1 Comment disposer d'un emplacement pour y ranger une chaîne417
3.2 Comment agir sur le contenu d'une chaîne418
3.3 Comment utiliser une chaîne existante421
4. Entrées-sorties standards de chaînes
423
4.1 Généralités423
4.2 Écriture de chaînes avec puts424
4.3 Écriture de chaînes avec le code de format %s de printf ou fprintf425
4.4 Lecture de chaînes avec gets426
4.5 Lecture de chaînes avec le code de format %s dans scanf ou fscanf429
4.6 Comparaison entre gets et scanf dans les lectures de chaînes430
4.7 Limitation de la longueur des chaînes lues sur l'entrée standard431
5. Généralités concernant les fonctions de manipulation de chaînes
435
5.1 Ces fonctions travaillent toujours sur des adresses435
5.2 Les adresses sont toujours de type char *435
5.3 Certains arguments sont déclarés const, d'autres pas436
5.4 Attention aux valeurs des arguments de limitation de longueur437
5.5 La fonction strlen438
6. Les fonctions de copie des chaînes
439
6.1 Généralités439
6.2 La fonction strcpy439
6.3 La fonction strncpy443
7. Les fonctions de concaténation de chaînes
446
7.1 Généralités446
7.2 La fonction strcat446
7.3 La fonction strncat449
8. Les fonctions de comparaison de chaînes
452
8.1 Généralités452
8.2 La fonction strcmp453
8.3 La fonction strncmp454
9. Les fonctions de recherche dans une chaîne
454
9.1 Les fonctions de recherche d'un caractère : strchr et strrchr455
9.2 La fonction de recherche d'une sous-chaîne : strstr458
9.3 La fonction de recherche d'un caractère parmi plusieurs : strpbrk458
9.4 Les fonctions de recherche d'un préfixe459
9.5 La fonction d'éclatement d'une chaîne : strtok461
10. Les fonctions de conversion d'une chaîne en un nombre
464
10.1 Généralités464
10.2 La fonction de conversion d'une chaîne en un double : strtod465
10.3 Les fonctions de conversion d'une chaîne en entier : strtol et strtoul469
10.4 Cas particulier des fonctions atof, atoi et atol475
11. Les fonctions de manipulation de suites d'octets
475
11.1 Généralités476
11.2 Les fonctions de recopie de suites d'octets476
11.3 La fonction memcmp de comparaison de deux suites d'octets477
11.4 La fonction memset d'initialisation d'une suite d'octets478
11.5 La fonction memchr de recherche d'une valeur dans une suite d'octets479
Chapitre 11
Les types structure, union et énumération481
1. Exemples introductifs
482
1.1 Exemple d'utilisation d'une structure482
1.2 Exemple d'utilisation d'une union484
2. La déclaration des structures et des unions
486
2.1 Définition conseillée d'un type structure ou union486
2.2 Déclaration de variables utilisant des types structure ou union490
2.3 Déclaration partielle ou déclaration anticipée492
2.4 Mixage entre définition et déclaration493
2.5 L'espace de noms des identificateurs de champs494
2.6 L'espace de noms des identificateurs de types495
3. Représentation en mémoire d'une structure ou d'une union
495
3.1 Contraintes générales496
3.2 Cas des structures497
3.3 Cas des unions498
3.4 L'opérateur sizeof appliqué aux structures ou aux unions499
4. Utilisation d'objets de type structure ou union
499
4.1 Manipulation individuelle des différents champs d'une structure ou d'une union500
4.2 Affectation globale entre structures ou union de même type501
4.3 L'opérateur et appliqué aux structures ou aux unions503
4.4 Comparaison entre pointeurs sur des champs503
4.5 Comparaison des structures ou des unions par == ou != impossible504
4.6 L'opérateur ->504
4.7 Structure ou union transmise en argument ou en valeur de retour505
5. Exemples d'objets utilisant des structures
508
5.1 Structures comportant des tableaux508
5.2 Structures comportant d'autres structures509
5.3 Tableaux de structures510
5.4 Structure comportant des pointeurs sur des structures de son propre type511
6. Initialisation de structures ou d'unions
511
6.1 Initialisation par défaut des structures ou des unions512
6.2 Initialisation explicite des structures513
6.3 L'initialisation explicite d'une union517
7. Les champs de bits
517
7.1 Introduction517
7.2 Exemples introductifs518
7.3 Les champs de bits d'une manière générale519
7.4 Exemple d'utilisation d'une structure de champ de bits dans une union522
8. Les énumérations
523
8.1 Exemples introductifs523
8.2 Déclarations associées aux énumérations526
Chapitre 12
La définition de synonymes avec typedef529
1. Exemples introductifs
530
1.1 Définition d'un synonyme de int530
1.2 Définition d'un synonyme de int *530
1.3 Définition d'un synonyme de int[3]531
1.4 Définition d'un synonyme d'un type structure532
2. L'instruction typedef d'une manière générale
532
2.1 Syntaxe532
2.2 Définition de plusieurs synonymes533
2.3 Imbrication des définitions de synonyme534
3. Utilisation de synonymes
534
3.1 Un synonyme peut s'utiliser comme spécificateur de type534
3.2 Un synonyme n'est pas un nouveau type535
3.3 Un synonyme peut s'utiliser à la place d'un nom de type535
4. Les limitations de l'instruction typedef
536
4.1 Limitations liées à la syntaxe de typedef536
4.2 Cas des tableaux sans dimension537
4.3 Cas des synonymes de type fonction538
Chapitre 13
Les fichiers541
1. Généralités concernant le traitement des fichiers
542
1.1 Notion d'enregistrement542
1.2 Archivage de l'information sous forme binaire ou formatée542
1.3 Accès séquentiel ou accès direct543
1.4 Fichiers et implémentation544
2. Le traitement des fichiers en C
544
2.1 L'absence de la notion d'enregistrement en C545
2.2 Notion de flux545
2.3 Distinction entre fichier binaire et fichier formaté547
2.4 Opérations applicables à un fichier et choix du mode d'ouverture549
2.5 Accès séquentiel et accès direct551
2.6 Le tampon et sa gestion551
3. Le traitement des erreurs de gestion de fichier
552
3.1 Introduction552
3.2 La détection des erreurs en C553
4. Les entrées-sorties binaires : fwrite et fread
556
4.1 Exemple introductif de création séquentielle d'un fichier binaire556
4.2 Exemple introductif de liste séquentielle d'un fichier binaire559
4.3 La fonction fwrite561
4.4 La fonction fread564
5. Les opérations formatées avec fprintf, fscanf, fputs et fgets
568
5.1 Exemple introductif de création séquentielle d'un fichier formaté569
5.2 Exemple introductif de liste séquentielle d'un fichier formaté571
5.3 La fonction fprintf573
5.4 La fonction fscanf575
5.5 La fonction fputs579
5.6 La fonction fgets582
6. Les opérations mixtes portant sur des caractères
585
6.1 La fonction fputc et la macro putc586
6.2 La fonction fgetc et la macro getc589
7. L'accès direct
593
7.1 Exemple introductif d'accès direct à un fichier binaire existant593
7.2 La fonction fseek595
7.3 La fonction ftell597
7.4 Les possibilités de l'accès direct598
7.5 Détection des erreurs supplémentaires liées à l'accès direct600
7.6 Exemple d'accès indexé à un fichier formaté603
7.7 Les fonctions fsetpos et fgetpos605
8. La fonction fopen et les différents modes d'ouverture d'un fichier
605
8.1 Généralités605
8.2 La fonction fopen606
9. Les flux prédéfinis
609
Chapitre 14
La gestion dynamique611
1. Intérêt de la gestion dynamique
611
2. Exemples introductifs
612
2.1 Allocation et utilisation d'un objet de type double612
2.2 Cas particulier d'un tableau614
3. Caractéristiques générales de la gestion dynamique
615
3.1 Absence de typage des objets616
3.2 Notation des objets616
3.3 Risques et limitations617
3.4 Limitations618
4. La fonction malloc
618
4.1 Prototype618
4.2 La valeur de retour et la gestion des erreurs619
5. La fonction free
620
6. La fonction calloc
620
6.1 Prototype621
6.2 Rôle621
6.3 Valeur de retour et gestion des erreurs621
6.4 Précautions622
7. La fonction realloc
623
7.1 Exemples introductifs623
7.2 Prototype624
7.3 Rôle624
7.4 Valeur de retour625
7.5 Précautions626
8. Techniques utilisant la gestion dynamique
626
8.1 Gestion de tableaux dont la taille n'est connue qu'au moment de l'exécution626
8.2 Gestion de tableaux dont la taille varie pendant l'exécution627
8.3 Gestion de listes chaînées628
Chapitre 15
Le préprocesseur631
1. Généralités
631
1.1 Les directives tiennent compte de la notion de ligne631
1.2 Les directives et le caractère #632
1.3 La notion de token pour le préprocesseur632
1.4 Classification des différentes directives du préprocesseur633
2. La directive de définition de symboles et de macros
634
2.1 Exemples introductifs634
2.2 La syntaxe de la directive #define637
2.3 Règles d'expansion d'un symbole ou d'une macro640
2.4 L'opérateur de conversion en chaîne : #650
2.5 L'opérateur de concaténation de tokens : ##653
2.6 Exemple faisant intervenir les deux opérateurs # et ##655
2.7 La directive #undef655
2.8 Précautions à prendre656
2.9 Les symboles prédéfinis660
3. Les directives de compilation conditionnelle
661
3.1 Compilation conditionnelle fondée sur l'existence de symboles661
3.2 Compilation conditionnelle fondée sur des expressions664
3.3 Imbrication des directives de compilation conditionnelle670
3.4 Exemples d'utilisation des directives de compilation conditionnelle670
4. La directive d'inclusion de fichier source
672
4.1 Généralités672
4.2 Syntaxe673
4.3 Précautions à prendre674
5. Directives diverses
677
5.1 La directive vide677
5.2 La directive line678
5.3 La directive error678
5.4 La directive pragma679
Chapitre 16
Les déclarations681
1. Généralités
681
1.1 Les principaux éléments : déclarateur et spécificateur de type682
1.2 Les autres éléments683
2. Syntaxe générale d'une déclaration
684
2.1 Forme générale d'une déclaration685
2.2 Spécificateur de type structure686
2.3 Spécificateur de type union688
2.4 Spécificateur de type énumération689
2.5 Déclarateur689
3. Définition de fonction
691
3.1 Forme moderne de la définition d'une fonction691
3.2 Forme ancienne de la définition d'une fonction692
4. Interprétation de déclarations
692
4.1 Les règles692
4.2 Exemples693
5. Écriture de déclarateurs
695
5.1 Les règles695
5.2 Exemples696
Chapitre 17
Fiabilisation des lectures au clavier699
1. Généralités
699
2. Utilisation de scanf
701
3. Utilisation de gets
702
4. Utilisation de fgets
703
4.1 Pour éviter le risque de débordement en mémoire703
4.2 Pour ignorer les caractères excédentaires704
4.3 Pour traiter l'éventuelle fin de fichier et paramétrer la taille des chaînes lues706
Chapitre 18
Les catégories de caractères et les fonctions associées709
1. Généralités
709
1.1 Dépendance de l'implémentation et de la localisation709
1.2 Les fonctions de test710
2. Les catégories de caractères
710
3. Exemples
713
3.1 Pour obtenir la liste de tous les caractères imprimables et leur code713
3.2 Pour connaître les catégories des caractères d'une implémentation714
4. Les fonctions de transformation de caractères
715
Chapitre 19
Gestion des gros programmes717
1. Utilisation de variables globales
718
1.1 Avantages des variables globales719
1.2 Inconvénients des variables globales719
1.3 Conseils en forme de compromis720
2. Partage d'identificateurs entre plusieurs fichiers source
721
2.1 Cas des identificateurs de fonctions721
2.2 Cas des identificateurs de types ou de synonymes722
2.3 Cas des variables globales723
Chapitre 20
Les arguments variables725
1. Écriture de fonctions à arguments variables
725
1.1 Exemple introductif725
1.2 Arguments variables, forme d'en-tête et déclaration727
1.3 Contraintes imposées par la norme728
1.4 Syntaxe et rôle des macros va_start, va_arg et va_end729
2. Transmission d'une liste variable
730
3. Les fonctions vprintf, vfprintf et vsprintf
732
Chapitre 21
Communication avec l'environnement735
1. Cas particulier des programmes autonomes
735
2. Les arguments reçus par la fonction main
736
2.1 L'en-tête de la fonction main736
2.2 Récupération des arguments reçus par la fonction main737
3. Terminaison d'un programme
738
3.1 Les fonctions exit et atexit738
3.2 L'instruction return dans la fonction main739
4. Communication avec l'environnement
740
4.1 La fonction getenv740
4.2 La fonction system741
5. Les signaux
741
5.1 Généralités741
5.2 Exemple introductif742
5.3 La fonction signal744
5.4 La fonction raise746
Chapitre 22
Les caractères étendus747
1. Le type wchar_t et les caractères multioctets
748
2. Notation des constantes du type wchar_t
749
3. Les fonctions liées aux caractères étendus mblen, mbtowc et wctomb
750
3.1 Généralités750
3.2 La fonction mblen750
3.3 La fonction mbtowc751
3.4 La fonction wctomb751
4. Les chaînes de caractères étendus
752
5. Représentation des constantes chaînes de caractères étendus
753
6. Les fonctions liées aux chaînes de caractères étendus : mbstowcs et wcstombs
753
6.1 La fonction mbstowcs754
6.2 La fonction wcstombs754
Chapitre 23
Les adaptations locales755
1. Le mécanisme de localisation
755
2. La fonction setlocale
756
3. La fonction localeconv
758
Chapitre 24
La récursivité761
1. Notion de récursivité
761
2. Exemple de fonction récursive
762
3. L'empilement des appels
763
4. Autre exemple de récursivité
765
Chapitre 25
Les branchements non locaux769
1. Exemple introductif
769
2. La macro setjmp et la fonction longjmp
770
2.1 Prototypes et rôles770
2.2 Contraintes d'utilisation771
Chapitre 26
Les incompatibilités entre C et C++773
1. Les incompatibilités raisonnables
773
1.1 Définition d'une fonction773
1.2 Les prototypes en C++774
1.3 Fonctions sans valeur de retour774
1.4 Compatibilité entre le type void * et les autres pointeurs774
1.5 Les déclarations multiples775
1.6 L'instruction goto775
1.7 Initialisation de tableaux de caractères776
2. Les incompatibilités incontournables
776
2.1 Fonctions sans arguments776
2.2 Le qualifieur const776
2.3 Les constantes de type caractère778
Annexe A
La bibliothèque standard C90779
1. Généralités
780
1.1 Les différents fichiers en-tête780
1.2 Redéfinition d'une macro standard par une fonction781
2. Assert.h : macro de mise au point
781
3. Ctype.h : tests de caractères et conversions majuscules - minuscules
782
3.1 Les fonctions de test d'appartenance d'un caractère à une catégorie782
3.2 Les fonctions de transformation de caractères783
4. Errno.h : gestion des erreurs
783
4.1 Constantes prédéfinies783
4.2 Macros783
5. Locale.h : caractéristiques locales
784
5.1 Types prédéfinis784
5.2 Constantes prédéfinies784
5.3 Fonctions784
6. Math.h : fonctions mathématiques
784
6.1 Constantes prédéfinies784
6.2 Traitement des conditions d'erreur785
6.3 Fonctions trigonométriques785
6.4 Fonctions hyperboliques786
6.5 Fonctions exponentielle et logarithme786
6.6 Fonctions puissance787
6.7 Autres fonctions787
7. Setjmp.h : branchements non locaux
788
7.1 Types prédéfinis788
7.2 Fonctions et macros788
8. Signal.h : traitement de signaux
788
8.1 Types prédéfinis788
8.2 Constantes prédéfinies788
8.3 Fonctions de traitement de signaux789
9. Stdarg.h : gestion d'arguments variables
789
9.1 Types prédéfinis789
9.2 Macros789
10. Stddef.h : définitions communes
790
10.1 Types prédéfinis790
10.2 Constantes prédéfinies790
10.3 Macros prédéfinies790
11. Stdio.h : entrées-sorties790
11.1 Types prédéfinis790
11.2 Constantes prédéfinies790
11.3 Fonctions d'opérations sur les fichiers791
11.4 Fonctions d'accès aux fichiers792
11.5 Fonctions d'écriture formatée793
11.6 Fonctions de lecture formatée794
11.7 Fonctions d'entrées-sorties de caractères795
11.8 Fonctions d'entrées-sorties sans formatage797
11.9 Fonctions agissant sur le pointeur de fichier798
11.10 Fonctions de gestion des erreurs d'entrée-sortie799
12. Stdlib.h : utilitaires
800
12.1 Types prédéfinis800
12.2 Constantes prédéfinies800
12.3 Fonctions de conversion de chaîne800
12.4 Fonctions de génération de séquences de nombres pseudo aléatoires802
12.5 Fonctions de gestion de la mémoire803
12.6 Fonctions de communication avec l'environnement804
12.7 Fonctions de tri et de recherche805
12.8 Fonctions liées à l'arithmétique entière805
12.9 Fonctions liées aux caractères étendus806
12.10 Fonctions liées aux chaînes de caractères étendus806
13. String.h : manipulations de suites de caractères
807
13.1 Types prédéfinis807
13.2 Constantes prédéfinies807
13.3 Fonctions de copie807
13.4 Fonctions de concaténation808
13.5 Fonctions de comparaison808
13.6 Fonctions de recherche809
13.7 Fonctions diverses810
Time.h : gestion de l'heure et de la date
811
14.1 Types prédéfinis811
14.2 Constantes prédéfinies812
14.3 Fonctions de manipulation de temps812
14.4 Fonctions de conversion813
Annexe B
Les normes C99 et C11815
1. Contraintes supplémentaires (C99)
815
1.1 Type de retour d'une fonction815
1.2 Déclaration implicite d'une fonction815
1.3 Instruction return816
2. Division d'entiers (C99)
816
3. Emplacement des déclarations (C99)
816
4. Commentaires de fin de ligne (C99)
817
5. Tableaux de dimension variable (C99, facultatif en C11)
818
5.1 Dans les déclarations818
5.2 Dans les en-têtes de fonctions et leurs prototypes818
6. Nouveaux types (C99)
819
6.1 Nouveau type entier long long (C99)819
6.2 Types entiers étendus (C99)819
6.3 Nouveaux types flottants (C99)820
6.4 Le type booléen (C99)820
6.5 Les types complexes (C99, facultatif en C11)821
7. Nouvelles fonctions mathématiques (C99)
822
7.1 Généralisation aux trois types flottants (C99)823
7.2 Nouvelles fonctions (C99)823
7.3 Fonctions mathématiques génériques (C99)824
8. Les fonctions en ligne (C99)
825
9. Les caractères étendus (C99) et Unicode (C11)
826
10. Les pointeurs restreints (C99)
826
11. La directive pragma (C99)
827
12. Les calculs flottants (C99)
827
12.1 La norme IEEE 754827
12.2 Choix du mode d'arrondi828
12.3 Gestion des situations d'exception828
12.4 Manipulation de l'ensemble de l'environnement de calcul flottant829
13. Structures incomplètes (C99)
829
14. Structures anonymes (C11)
829
15. Expressions fonctionnelles génériques (C11)
830
16. Gestion des contraintes d'alignement (C11)
830
17. Fonctions vérifiant le débordement mémoire (C11 facultatif)
830
18. Les threads (C11 facultatif)
831
19. Autres extensions de C99
831
20. Autres extensions de C11
831
Index833