08.04.2014 Views

Algorithmique et Langage - Pages de Michel Deloizy - Free

Algorithmique et Langage - Pages de Michel Deloizy - Free

Algorithmique et Langage - Pages de Michel Deloizy - Free

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Licence L1<br />

<strong>Algorithmique</strong> <strong>et</strong> <strong>Langage</strong><br />

II22<br />

Cours<br />

Travaux dirigés<br />

Travaux pratiques<br />

M. <strong>Deloizy</strong> http://michel.<strong>de</strong>loizy.free.fr<br />

Édition du 15 janvier 2005


Introduction à l'informatique<br />

Notion d'algorithme<br />

Généralités<br />

Rappels<br />

M. <strong>Deloizy</strong> Informatique - Généralités 1<br />

M. <strong>Deloizy</strong> Informatique - Généralités 2<br />

Algorithme<br />

• Ensemble <strong>de</strong> règles opératoires propres à<br />

un calcul<br />

• Calcul, enchaînement <strong>de</strong>s actions<br />

nécessaires à l'accomplissement d'une<br />

tâche<br />

• P<strong>et</strong>it Robert :<br />

Métho<strong>de</strong> proposée pour le traitement d'un<br />

problème par un automate<br />

Humain ou machine Traitement systématique<br />

M. <strong>Deloizy</strong> Informatique - Généralités 3<br />

Exemple d'algorithme<br />

• Rec<strong>et</strong>te <strong>de</strong> cuisine :<br />

– Nom <strong>de</strong> la rec<strong>et</strong>te<br />

– Ingrédients<br />

– Réalisation<br />

… Gâteau au yaourt …<br />

M. <strong>Deloizy</strong> Informatique - Généralités 4<br />

1


Définition d'un algorithme<br />

• But recherché<br />

– (que doit faire l'algorithme ?)<br />

… un gâteau au yaourt pour 6 personnes<br />

• Outils disponibles<br />

– Opérateurs, données, règles associées<br />

Yaourts, œufs, sucre, huile, sel, levure, moule, four<br />

• Enchaînement <strong>de</strong>s actions<br />

– Ordre <strong>de</strong> traitement<br />

Description <strong>de</strong> la séquence d'actions nécessaires à la<br />

réalisation <strong>de</strong> la rec<strong>et</strong>te<br />

Algorithme universel<br />

• Non lié à un langage <strong>de</strong> programmation<br />

• Non lié à une machine<br />

Mais<br />

• Peut être plus ou moins adapté à un type<br />

d'automate<br />

M. <strong>Deloizy</strong> Informatique - Généralités 5<br />

M. <strong>Deloizy</strong> Informatique - Généralités 6<br />

Exemple : Multiplication<br />

Multiplication à la Russe<br />

• Classique :<br />

34 x 15 → 510<br />

Nécessite la connaissance <strong>de</strong>s tables <strong>de</strong><br />

multiplication<br />

34<br />

17<br />

8<br />

4<br />

2<br />

1<br />

15<br />

30<br />

60<br />

120<br />

240<br />

480<br />

510<br />

Uniquement<br />

<strong>de</strong>s multiplications<br />

par 2,<br />

<strong>de</strong>s divisions par 2<br />

<strong>et</strong> <strong>de</strong>s additions<br />

→ adapté au calcul<br />

par <strong>de</strong>s circuits<br />

logiques<br />

M. <strong>Deloizy</strong> Informatique - Généralités 7<br />

M. <strong>Deloizy</strong> Informatique - Généralités 8<br />

2


Algorithmes multiples<br />

• Pour résoudre une application, il existe<br />

souvent plusieurs algorithmes.<br />

Le choix sera fait selon :<br />

– La rapidité d'exécution<br />

– La facilité <strong>de</strong> mise en œuvre par l'automate<br />

– Le type <strong>de</strong> données à traiter<br />

Support matériel<br />

Architecture d'un ordinateur<br />

M. <strong>Deloizy</strong> Informatique - Généralités 9<br />

M. <strong>Deloizy</strong> Informatique - Généralités 10<br />

Architecture d'un ordinateur<br />

• 3 éléments :<br />

– Le processeur<br />

– La mémoire<br />

– Les périphériques<br />

Le processeur<br />

• Le cœur du système<br />

• Rôle :<br />

– Traiter <strong>de</strong>s informations binaires<br />

• Lire <strong>de</strong>s informations <strong>de</strong>puis la mémoire<br />

• Écrire <strong>de</strong>s informations dans la mémoire<br />

• Réaliser <strong>de</strong>s opérations élémentaires sur infos.<br />

• Traitement <strong>de</strong>s informations selon un "programme"<br />

→ lu <strong>de</strong> manière séquentielle au rythme d'une horloge<br />

M. <strong>Deloizy</strong> Informatique - Généralités 11<br />

M. <strong>Deloizy</strong> Informatique - Généralités 12<br />

3


La mémoire<br />

• Stockage<br />

– Des informations<br />

– Des programmes<br />

•ROM<br />

– Données permanentes<br />

•RAM<br />

– Données temporaires<br />

– Utilisée par le processeur pour le traitement<br />

<strong>de</strong>s données <strong>et</strong> <strong>de</strong>s programmes<br />

La mémoire <strong>de</strong> masse<br />

• Stockage <strong>de</strong> gran<strong>de</strong> capacité<br />

– Ban<strong>de</strong>s magnétiques, disques, CD, DVD<br />

• Mémoire non volatile<br />

• Réinscriptible<br />

• Pas d'accès direct par le processeur<br />

→ mémoire "lente" (quelques ms)<br />

RAM : quelques ns<br />

M. <strong>Deloizy</strong> Informatique - Généralités 13<br />

M. <strong>Deloizy</strong> Informatique - Généralités 14<br />

Les Périphériques<br />

• Organes <strong>de</strong> communication<br />

• Disposés entre le processeur <strong>et</strong> le mon<strong>de</strong><br />

extérieur<br />

• Perm<strong>et</strong>tent les échanges avec :<br />

– L'utilisateur<br />

– Une autre machine<br />

• Exemples :<br />

– Écran, clavier, ports série ou parallèle, USB,<br />

réseaux, mo<strong>de</strong>m<br />

Le système d'exploitation<br />

• Perm<strong>et</strong> le dialogue entre l'utilisateur <strong>et</strong> la<br />

machine<br />

• Gestion <strong>de</strong>s ressources <strong>de</strong> l'ordinateur<br />

• Scrutation permanente <strong>de</strong>s sollicitations <strong>de</strong><br />

l'environnement<br />

→ Contient un interpréteur <strong>de</strong> comman<strong>de</strong>s<br />

• Exemples :<br />

–MS-DOS<br />

– Windows<br />

–Unix, …<br />

M. <strong>Deloizy</strong> Informatique - Généralités 15<br />

M. <strong>Deloizy</strong> Informatique - Généralités 16<br />

4


Les outils <strong>de</strong> développement<br />

• L'éditeur <strong>de</strong> texte<br />

• L'assembleur<br />

• Le compilateur<br />

• L'éditeur <strong>de</strong> liens<br />

• Le débuggeur<br />

• L'interpréteur<br />

M. <strong>Deloizy</strong> Informatique - Généralités 17<br />

L'éditeur <strong>de</strong> textes<br />

• Programme perm<strong>et</strong>tant la saisie du texte<br />

contenant le programme source<br />

– Éditeur pleine page<br />

– Enregistrement <strong>et</strong> récupération <strong>de</strong> fichier en<br />

mémoire <strong>de</strong> masse<br />

– Modification aisée du texte<br />

– Outils divers :<br />

• Copier-coller<br />

• Recherche, remplacement<br />

– Ai<strong>de</strong> à la lisibilité (in<strong>de</strong>ntation, coloration, …)<br />

M. <strong>Deloizy</strong> Informatique - Généralités 18<br />

Le co<strong>de</strong> machine<br />

• Programme "lu" par le processeur : binaire<br />

→ co<strong>de</strong> machine<br />

Exemple :<br />

B6 30 00 charger A par cont. 3000H<br />

8B 05 ajouter 05H à A<br />

F7 30 01 ranger le résultat en 3001H<br />

• Programmation longue <strong>et</strong> fastidieuse<br />

• Très peu lisible, risque d'erreurs élevé<br />

M. <strong>Deloizy</strong> Informatique - Généralités 19<br />

L'assembleur<br />

• Écriture du co<strong>de</strong> machine en texte clair<br />

→ utilisation <strong>de</strong> mnémoniques<br />

Exemple :<br />

LDAA $3000 charger A par cont. 3000H<br />

ADDA #$05<br />

ajouter 05H à A<br />

STAA $3001 ranger le résultat en 3001H<br />

• Saisie du texte par un éditeur <strong>de</strong> textes<br />

• Texte traduit en co<strong>de</strong> machine par un<br />

programme : l'assembleur<br />

→ Amélioration <strong>de</strong> la lisibilité<br />

M. <strong>Deloizy</strong> Informatique - Généralités 20<br />

5


Problèmes liés à l'assembleur<br />

• <strong>Langage</strong> du processeur<br />

– Très différent du langage naturel<br />

– Pas <strong>de</strong> gestion évoluée <strong>de</strong>s données<br />

– Pas <strong>de</strong> système <strong>de</strong> protection<br />

– Propre à chaque processeur<br />

→ Maintenance difficile<br />

→ Portabilité nulle<br />

Mais :<br />

gran<strong>de</strong> efficacité (pour un bon programmeur)<br />

Le compilateur<br />

•But :<br />

– S'affranchir du type <strong>de</strong> processeur<br />

– S'affranchir <strong>de</strong> l'environnement matériel <strong>et</strong><br />

logiciel<br />

– Écriture <strong>de</strong>s programmes en langage naturel<br />

→ langage évolué<br />

• Compilateur :<br />

– Traduit le texte (source) en co<strong>de</strong> machine<br />

M. <strong>Deloizy</strong> Informatique - Généralités 21<br />

M. <strong>Deloizy</strong> Informatique - Généralités 22<br />

Utilisation d'un compilateur<br />

• Bonne lisibilité <strong>de</strong>s programmes<br />

• Bonne portabilité<br />

• Gestion <strong>de</strong> données complexes<br />

• Gestion <strong>de</strong> la mémoire du système<br />

• Gestion standard <strong>de</strong>s périphériques<br />

• Rapidité d'écriture <strong>de</strong>s programmes<br />

• Maintenance aisée<br />

En + :<br />

• Optimisation <strong>de</strong>s programmes<br />

• Systèmes <strong>de</strong> protection, gar<strong>de</strong>-fous<br />

Défaut <strong>de</strong>s compilateurs<br />

• <strong>Langage</strong> évolué très différent du langage<br />

machine<br />

→ traduction parfois difficile<br />

→ surco<strong>de</strong> parfois excessif<br />

– Exécutable volumineux, lent<br />

• Vrai avec processeurs anciens ou peu<br />

performants<br />

M. <strong>Deloizy</strong> Informatique - Généralités 23<br />

M. <strong>Deloizy</strong> Informatique - Généralités 24<br />

6


L'éditeur <strong>de</strong> liens<br />

• Création d'un programme :<br />

– Écriture d'un programme source (texte)<br />

Compilation<br />

– Programme obj<strong>et</strong> (binaire, co<strong>de</strong> machine<br />

incompl<strong>et</strong>)<br />

Éditeur <strong>de</strong> liens<br />

Bibliothèques personnelles<br />

Bibliothèques du langage<br />

– Programme exécutable (binaire autonome)<br />

Utilisation <strong>de</strong> l'éditeur <strong>de</strong> liens<br />

• Bibliothèques personnelles<br />

→ extension du langage à sa convenance<br />

• Portions <strong>de</strong> programmes réutilisables<br />

• Dépannage ou amélioration d'une<br />

bibliothèque<br />

⇒ dépannage ou amélioration <strong>de</strong> tous les<br />

programmes qui en dépen<strong>de</strong>nt<br />

M. <strong>Deloizy</strong> Informatique - Généralités 25<br />

M. <strong>Deloizy</strong> Informatique - Généralités 26<br />

Le débuggeur<br />

• Outil perm<strong>et</strong>tant le dépannage <strong>de</strong>s programmes<br />

(exécutables)<br />

– Consultation <strong>de</strong>s données<br />

– Exécution instruction par instruction<br />

– Points d'arrêt<br />

• Souvent intégré dans<br />

IDE (Integrated Development Environment)<br />

ou EDE (Embed<strong>de</strong>d Development Environment)<br />

→ Éditeur + Compilateur + Éditeur <strong>de</strong> liens + Débugger<br />

M. <strong>Deloizy</strong> Informatique - Généralités 27<br />

L'interpréteur<br />

• Exécute le programme pendant la lecture<br />

du co<strong>de</strong> source<br />

– Très lent (chaque instruction est interprétée<br />

puis exécutée à chaque utilisation)<br />

– Présence <strong>de</strong> la totalité <strong>de</strong>s bibliothèques du<br />

langage indispensable<br />

– Le programme n'est pas autonome (exécuté<br />

sous le contrôle <strong>de</strong> l'interpréteur)<br />

– Pas d'éditeur <strong>de</strong> liens<br />

– Pas d'optimisation <strong>de</strong> co<strong>de</strong><br />

M. <strong>Deloizy</strong> Informatique - Généralités 28<br />

7


Représentation <strong>de</strong>s données<br />

Données utilisées en<br />

informatique<br />

• Types <strong>de</strong>s données<br />

– Choisi en fonction <strong>de</strong> l'utilisation<br />

Exemples :<br />

• Comptage d'un nombre d'étudiants<br />

• Calcul du sinus d'un angle<br />

• Écriture d'un texte<br />

• Données codées en binaire<br />

– Pour le traitement par le processeur<br />

– Définition d'un mo<strong>de</strong> <strong>de</strong> rangement en mémoire pour<br />

chaque type <strong>de</strong> donnée<br />

• Limitations liées au codage utilisé<br />

M. <strong>Deloizy</strong> Informatique - Généralités 29<br />

M. <strong>Deloizy</strong> Informatique - Généralités 30<br />

Le type entier<br />

Valeurs limites<br />

•Signé :<br />

– …, -2, -1, 0, 1, 2, …<br />

• Non signé<br />

– 0, 1, 2, …<br />

• Traitement <strong>de</strong> données entières<br />

– Adapté aux énumérations<br />

Codage<br />

8 bits<br />

16 bits<br />

32 bits<br />

Signé<br />

min max<br />

-128 127<br />

80 H 7F H<br />

-32768<br />

-2147483648<br />

32767<br />

2147483647<br />

min<br />

0<br />

0 H<br />

0<br />

0<br />

Non signé<br />

max<br />

255<br />

FF H<br />

65535<br />

4294967295<br />

M. <strong>Deloizy</strong> Informatique - Généralités 31<br />

Rem. : En représentation signée, le signe du nombre est donné<br />

par le bit <strong>de</strong> poids le plus fort (1 pour négatif)<br />

M. <strong>Deloizy</strong> Informatique - Généralités 32<br />

8


Opérations possibles<br />

• Arithmétiques<br />

! Addition (+)<br />

! Soustraction (-)<br />

! Multiplication(*)<br />

! Division entière (/)<br />

! Modulo (%) Reste <strong>de</strong> la division entière<br />

Opérations possibles<br />

• Logiques (bit à bit)<br />

! ET logique (&)<br />

! OU logique (|)<br />

! OU exclusif (^)<br />

! Complément à 1 (~)<br />

• Comparaisons<br />

! ==, , =, !=<br />

M. <strong>Deloizy</strong> Informatique - Généralités 33<br />

M. <strong>Deloizy</strong> Informatique - Généralités 34<br />

• ±nnn<br />

! 12, -5, +3, 0<br />

Notation<br />

Utilisation<br />

• Intérêt <strong>de</strong>s entiers :<br />

– Valeurs exactes, pas d'imprécision<br />

– Adaptés au comptage, dénombrement<br />

• Inconvénient :<br />

– Dynamique limitée<br />

• Pas <strong>de</strong> très grand nombre<br />

• Pas <strong>de</strong> très p<strong>et</strong>it nombre<br />

– Inadaptés au calcul scientifique<br />

M. <strong>Deloizy</strong> Informatique - Généralités 35<br />

M. <strong>Deloizy</strong> Informatique - Généralités 36<br />

9


Le type booléen<br />

• Résultat d'une expression logique<br />

• 2 valeurs possibles :<br />

– Vrai ou Faux<br />

• Opérateurs :<br />

– ET, OU, NON : résultat booléen<br />

Ex. : Vrai OU Faux → Vrai<br />

Vrai ET Vrai → Vrai<br />

NON Vrai → Faux<br />

• Codage :<br />

– 1 bit suffit<br />

M. <strong>Deloizy</strong> Informatique - Généralités 37<br />

Le type à virgule flottante<br />

• Nombres réels (positifs <strong>et</strong> négatifs)<br />

• Notation mantisse – exposant<br />

• Perm<strong>et</strong>tent une gran<strong>de</strong> dynamique :<br />

– Très p<strong>et</strong>ites valeurs (Ex. : ±1.6 10 -19 )<br />

– Très gran<strong>de</strong>s valeurs (Ex. : 25.2 10 47 )<br />

• Problème d'imprécision :<br />

– Ex. : entre 2.0 <strong>et</strong> 2.1 → infinité <strong>de</strong> valeurs<br />

codage machine ⇒ nombre <strong>de</strong> valeurs fini<br />

– Présence d'arrondis<br />

M. <strong>Deloizy</strong> Informatique - Généralités 38<br />

Codage<br />

• Exemple <strong>de</strong> codage sur 32 bits (IEEE)<br />

– Mantisse sur 24 bits<br />

– Exposant sur 8 bits<br />

± m . 2 e<br />

! S : signe (1 : négatif, 0 : positif)<br />

! m : mantisse (1 ≤ m < 2) ⇒ m = 1.xxxxx<br />

! e : exposant (-128 ≤ e ≤ 127)<br />

! f : partie fractionnaire <strong>de</strong> la mantisse<br />

! e' : e+127 (1 ≤ e' ≤ 254)<br />

e'<br />

f<br />

S<br />

b 31 b 30 b 23 b 22<br />

… b 0<br />

M. <strong>Deloizy</strong> Informatique - Généralités 39<br />

Valeurs limites<br />

e'<br />

f<br />

S<br />

b 31 b 30 b 23 b 22<br />

… b 0<br />

• Valeur la plus p<strong>et</strong>ite positive :<br />

–S = 0<br />

–e' = 1 ⇒ e = -126<br />

–f = 0 ⇒ m = 1.0<br />

V min = 1.0 2 -126 ≈ 1.175 10 -38<br />

• Valeur la plus gran<strong>de</strong> positive :<br />

–S = 0<br />

– e' = 254 ⇒ e = 127<br />

– f = 0.11111… ⇒ m = 1.11111… = 2.0 – 2 -23<br />

V max = (2.0 – 2 -23 ) 2 127 ≈ 3.403 10 38<br />

M. <strong>Deloizy</strong> Informatique - Généralités 40<br />

10


Résolution<br />

• Valeur suivante <strong>de</strong> 1.0 :<br />

1.0 + 2 -23 = 1.0 + 1.2 10 -7<br />

→ 6 chiffres significatifs<br />

Valeurs particulières<br />

± m . 2 e avec m>1 ne perm<strong>et</strong> pas <strong>de</strong> co<strong>de</strong>r 0.0<br />

• Si e' = 0 → codage <strong>de</strong> 0.0<br />

• Si e' = 255 → codage <strong>de</strong> ±NAN<br />

M. <strong>Deloizy</strong> Informatique - Généralités 41<br />

M. <strong>Deloizy</strong> Informatique - Généralités 42<br />

• Sur 64 bits (8 oct<strong>et</strong>s) :<br />

– Mantisse sur 52 bits<br />

– Exposant sur 11 bits<br />

– Signe sur 1 bit<br />

Autres codages<br />

– 15 chiffres significatifs<br />

– Valeurs limites ≈ 10 ±308<br />

Opérations possibles<br />

• Arithmétiques<br />

! Addition (+)<br />

! Soustraction (-)<br />

! Multiplication(*)<br />

! Division (/)<br />

• Comparaisons<br />

! ==, , =, !=<br />

• Sur 80 bits → 18 chiffres significatifs, ≈ 10 ±4932 M. <strong>Deloizy</strong> Informatique - Généralités 44<br />

M. <strong>Deloizy</strong> Informatique - Généralités 43<br />

11


Notation<br />

Forme générale :<br />

±dd.ddE±xx ⇔ ±dd.dd 10 ±xx<br />

• ±nnn.nnn<br />

! 2.0, -1.432, +4.5, 0.0<br />

• ±.nnn ou ± nnn.<br />

! 1. , -.2, 0.<br />

• ± nnE ±nn ou ± nne ±nn<br />

! 1E3, 5.22e-23, +3.2E-2<br />

M. <strong>Deloizy</strong> Informatique - Généralités 45<br />

Le type caractère<br />

• Caractères codés pour représentation en<br />

machine<br />

• 7 bits suffisent (128 caractères)<br />

• Exemple <strong>de</strong> co<strong>de</strong> : ASCII<br />

– American Standard Co<strong>de</strong> for Information<br />

Interchange<br />

– Défini par ANSI (American National Standard<br />

Institute)<br />

M. <strong>Deloizy</strong> Informatique - Généralités 46<br />

Codage ASCII<br />

• Contient :<br />

– L<strong>et</strong>tres minuscules <strong>et</strong> majuscules (ordre<br />

alphabétique) : 2x26 caractères<br />

– Chiffres (ordre croissant <strong>de</strong> 0 à 9)<br />

– Ponctuations, caractères typographiques, …<br />

– Caractères <strong>de</strong> contrôle (co<strong>de</strong>s 0 à 31)<br />

• Exemples :<br />

– 'A' = 65, 'B' = 66, 'Z' = 90, 'a' = 97, '0' = 48<br />

– CR = 13, LF = 10, TAB = 9, FF = 12, BEL = 7<br />

Autres codages<br />

• EBCDIC (IBM)<br />

• ANSI (jeux <strong>de</strong> caractères internationaux)<br />

• ASCII étendu<br />

Souvent sur 1 oct<strong>et</strong><br />

Rem. : le langage informatique prend en charge le<br />

codage (pas nécessaire <strong>de</strong> le connaître)<br />

M. <strong>Deloizy</strong> Informatique - Généralités 47<br />

M. <strong>Deloizy</strong> Informatique - Généralités 48<br />

12


Notation <strong>et</strong> opérations possibles<br />

• Notation :<br />

– 'X', '0', '2'<br />

– '\r', '\n', '\t'<br />

– '\\', '\'' (caractère d'échappement : \ )<br />

• Opérations possibles :<br />

– Additions, soustraction avec <strong>de</strong>s entiers<br />

Ex. : 'A' + 1 → 'B'<br />

– Comparaisons<br />

Ex. : 'A' < 'E'<br />

Chaînes <strong>de</strong> caractères<br />

• Ensemble ordonné <strong>de</strong> caractères<br />

représentant un mot, une phrase.<br />

• Particularité :<br />

– Nombre <strong>de</strong> caractères variable<br />

→ Taille très variable<br />

M. <strong>Deloizy</strong> Informatique - Généralités 49<br />

M. <strong>Deloizy</strong> Informatique - Généralités 50<br />

Codage<br />

• Codages possibles :<br />


Le type adresse<br />

• Données <strong>et</strong> programmes<br />

rangés en mémoire<br />

→ Chaque donnée,<br />

chaque instruction a une<br />

adresse propre<br />

→ Le processeur accè<strong>de</strong><br />

aux données <strong>et</strong> aux<br />

instructions grâce à leur<br />

adresse<br />

Contenu<br />

adresse mémoire<br />

C32C H 2A H<br />

C32D H F0 H<br />

C32E H 12 H<br />

C32F H 45 H<br />

C330 H C5 H<br />

Variable<br />

toto<br />

c1<br />

c2<br />

x<br />

Indirection<br />

• Une donnée peut<br />

contenir une adresse<br />

→ pointe sur une autre adresse<br />

donnée<br />

C32C H<br />

→ Ex. : ptr pointe sur c2 C32D H<br />

→ Pointeur<br />

C32E H<br />

→ On peut modifier c2 <strong>de</strong> C32F H<br />

manière indirecte en C330<br />

agissant sur ptr<br />

H<br />

→ Indirection<br />

Contenu<br />

mémoire<br />

C3 H<br />

2F H<br />

12 H<br />

45 H<br />

C5 H<br />

Variable<br />

ptr<br />

c1<br />

c2<br />

x<br />

Remarque : On peut avoir <strong>de</strong>s indirections multiples<br />

M. <strong>Deloizy</strong> Informatique - Généralités 53<br />

M. <strong>Deloizy</strong> Informatique - Généralités 54<br />

Les tableaux<br />

• Données rangées <strong>de</strong> manière contiguë en<br />

mémoire<br />

• Données indicées (vecteurs)<br />

• Tout type <strong>de</strong> donnée peut être organisé en<br />

tableau<br />

Exemple :<br />

• Caractéristiques d'un tableau :<br />

– Adresse du 1er élément<br />

– Nombre d'éléments<br />

– Type <strong>de</strong>s données contenues<br />

Constantes<br />

• Données non modifiables<br />

• Utilisées dans <strong>de</strong>s expressions<br />

• Exemple :<br />

P = 2.0 * PI * Rayon<br />

Constantes<br />

t 0 t 1 t 2 t n<br />

M. <strong>Deloizy</strong> Informatique - Généralités 56<br />

M. <strong>Deloizy</strong> Informatique - Généralités 55<br />

14


Constantes explicites<br />

• Valeur écrite explicitement<br />

– L'écriture indique le type <strong>de</strong> la constante :<br />

• 2, -3 : entiers<br />

• 1.0, 2E4 : virgules flottantes<br />

• 'z', '2' : caractères<br />

• "TOTO" : chaîne <strong>de</strong> caractères<br />

M. <strong>Deloizy</strong> Informatique - Généralités 57<br />

Constantes prédéfinies<br />

• Utilisées par l'intermédiaire d'un nom <strong>de</strong><br />

symbole<br />

• Utilisation i<strong>de</strong>ntique à constante explicite<br />

• Avantages :<br />

– Perm<strong>et</strong> une meilleure lisibilité<br />

– Facilite la maintenance<br />

– Évite <strong>de</strong>s écritures & modifications multiples<br />

→ réduit le risque d'erreurs<br />

Exemple : constante TVA = 0.196<br />

Pull_ttc = Pull_ht*(1+TVA)<br />

Chemise_ttc = Chemise_ht*(1+TVA)<br />

M. <strong>Deloizy</strong> Informatique - Généralités 58<br />

Constitution d'un programme<br />

Écriture d'un programme<br />

• Ensemble <strong>de</strong> fonctions ou procédures<br />

• Une fonction particulière :<br />

– démarrage du programme, point d'entrée<br />

Principes <strong>de</strong> base<br />

M. <strong>Deloizy</strong> Informatique - Généralités 59<br />

M. <strong>Deloizy</strong> Informatique - Généralités 60<br />

15


Fonctions<br />

• Composées d'instructions<br />

– Exécutées séquentiellement<br />

• Instructions :<br />

– Expressions, ex. : y=a+b, y=sin(a)<br />

– Contrôle <strong>de</strong> déroulement, ex. : si y


Classe d'allocation<br />

• Façon dont la donnée est créée par le<br />

compilateur :<br />

– Allocation statique :<br />

• Donnée créée au chargement du programme<br />

• Emplacement fixe pendant durée d'exécution<br />

• Valeur laissée précé<strong>de</strong>mment r<strong>et</strong>rouvée à chaque<br />

accès<br />

– Allocation dynamique :<br />

• Donnée créée lors <strong>de</strong> la déclaration<br />

• Valeur initiale aléatoire<br />

• Donnée détruite en fin d'utilisation<br />

Portée <strong>de</strong>s données<br />

• Données connues par la totalité du<br />

programme ou par une portion seulement :<br />

– Donnée globale<br />

• Toutes les fonctions du programme peuvent y<br />

accé<strong>de</strong>r<br />

– Donnée locale<br />

• Définie pour une portion <strong>de</strong> programme (par<br />

exemple une fonction)<br />

• Inconnue hors <strong>de</strong> c<strong>et</strong>te portion<br />

M. <strong>Deloizy</strong> Informatique - Généralités 65<br />

M. <strong>Deloizy</strong> Informatique - Généralités 66<br />

Règles <strong>de</strong> portée<br />

• Deux variables ne peuvent pas avoir le<br />

même nom dans la même zone <strong>de</strong> portée<br />

• Si une donnée locale porte le même nom<br />

qu'une donnée globale, la donnée globale<br />

<strong>de</strong>vient inaccessible<br />

→ masquage <strong>de</strong> la donnée globale<br />

Structures conditionnelles<br />

Contrôle du déroulement du<br />

programme<br />

M. <strong>Deloizy</strong> Informatique - Généralités 67<br />

M. <strong>Deloizy</strong> Informatique - Généralités 68<br />

17


Structure conditionnelle simple<br />

• Si alors …<br />

finsi<br />

if (x


Structure itérative Pour<br />

• Pour jusqu'à faire … FinPour<br />

– Facilité d'écriture<br />

– Peut être remplacé par Tant que<br />

for(i=0; i


Affectations autorisées<br />

• Entier ← Entier<br />

← Virgule flottante<br />

← Caractère<br />

• Virgule flottante ← Virgule flottante<br />

← Entier<br />

• Caractère ← Caractère<br />

← Entier<br />

• Booléen ← Booléen<br />

• Adresse ← Adresse<br />

Expressions<br />

• Arithmétiques ou logiques<br />

• Utilisation d'opérateurs :<br />

– Lecture <strong>de</strong> gauche à droite<br />

– Prise en compte <strong>de</strong>s priorités<br />

Ex. : y = 2*a + 3*b ⇔ y = (2*a) + (3*b)<br />

– Utilisation <strong>de</strong> ( ) pour forcer la priorité<br />

• Priorités classiques :<br />

! * <strong>et</strong> / ont la même priorité<br />

! - <strong>et</strong> + ont la même priorité<br />

! * <strong>et</strong> / sont prioritaires sur + <strong>et</strong> –<br />

– Les opérateurs logiques utilisent l'algèbre <strong>de</strong> Boole<br />

M. <strong>Deloizy</strong> Informatique - Généralités 77<br />

M. <strong>Deloizy</strong> Informatique - Généralités 78<br />

Exemple :<br />

y = a / 2 / x + 3* b / 2<br />

Priorités<br />

⇔<br />

y =<br />

2⋅<br />

Quand appel <strong>de</strong> fonction :<br />

– Arguments évalués avant l'appel<br />

– Fonction ⇔ variable calculée<br />

Ex. : y = 2 * sin(x)<br />

y = sin(a + acos(b)*2)<br />

a<br />

x<br />

3⋅b<br />

+<br />

2<br />

Opérateurs logiques<br />

• Utilisés dans les structures conditionnelles<br />

• Utilisent l'algèbre <strong>de</strong> Boole<br />

• ==, !=, , =, &&, ||, !<br />

Exemple :<br />

if( !( (x'z') ) ) …<br />

A B<br />

A + B = A⋅<br />

B<br />

if( (x>='a') && (x


Utilité <strong>de</strong>s fonctions<br />

Fonctions<br />

• Décomposer un problème complexe en sous problèmes<br />

plus simples<br />

– Analyse <strong>de</strong>scendante<br />

• Éviter la répétition <strong>de</strong> lignes <strong>de</strong> programmes<br />

• Améliorer la lisibilité<br />

• Faciliter la maintenance (constitution <strong>de</strong> bibliothèques)<br />

• Renvoie une valeur dépendant <strong>de</strong> paramètres transmis<br />

• Fonction qui ne renvoie rien :<br />

– Procédure, sous-programme<br />

M. <strong>Deloizy</strong> Informatique - Généralités 81<br />

M. <strong>Deloizy</strong> Informatique - Généralités 82<br />

Définition d'une fonction<br />

• À définir :<br />

– Nom <strong>de</strong> la fonction<br />

– Type <strong>de</strong> la valeur renvoyée<br />

– Type <strong>de</strong>s paramètres transmis<br />

Exemples : Utilisation :<br />

double sin(double x)<br />

y = sin(3.0);<br />

void clrscr(void) clrscr( );<br />

double pow(double y, double x) y = pow(2.0, 0.5)/2.0;<br />

Fonctions <strong>et</strong> paramètres<br />

• Lors <strong>de</strong> l'appel d'une fonction, les paramètres :<br />

– Sont tout d'abord évalués<br />

– Sont transmis dans l'ordre <strong>de</strong> leur écriture<br />

→ le type doit être compatible<br />

Exemple :<br />

void fct(int a, double x) {<br />

…<br />

}<br />

a, x : variables locales à fct<br />

…<br />

fct(3,2.0*sin(1.0));<br />

M. <strong>Deloizy</strong> Informatique - Généralités 83<br />

M. <strong>Deloizy</strong> Informatique - Généralités 84<br />

21


Transmission par valeur<br />

• La valeur du paramètre est recopiée<br />

→ Valeur initiale du paramètre (variable locale <strong>de</strong> la<br />

fonction)<br />

int somme(int a, int b) {<br />

int s;<br />

s = a+b;<br />

(15)<br />

r<strong>et</strong>urn s;<br />

}<br />

…<br />

X = somme(2, 5*3);<br />

Inconvénients <strong>de</strong> la transmission<br />

par valeur<br />

• Paramètre encombrant (ex. : tableau)<br />

• Une fonction ne renvoie qu'une valeur<br />

M. <strong>Deloizy</strong> Informatique - Généralités 85<br />

M. <strong>Deloizy</strong> Informatique - Généralités 86<br />

Transmission par référence<br />

Pointeurs<br />

• On transm<strong>et</strong> l'adresse du paramètre plutôt que<br />

sa valeur<br />

→ utilisation d'un pointeur (type adresse)<br />

int v;<br />

int *p;<br />

p = &v;<br />

v est un entier<br />

p est l'adresse d'un entier (*p : entier)<br />

p prend comme valeur l'adresse <strong>de</strong> v<br />

Pour accé<strong>de</strong>r à v, on utilise la notation *p<br />

→ signifie : l'entier pointé par p (ici : v)<br />

Pour charger 5 dans v, on peut donc écrire :<br />

v = 5<br />

*p = 5<br />

*(&v) = 5<br />

M. <strong>Deloizy</strong> Informatique - Généralités 87<br />

M. <strong>Deloizy</strong> Informatique - Généralités 88<br />

22


Pointeurs <strong>et</strong> fonctions<br />

int ProdQuot(int a, int b, int *p, int *q) {<br />

*p = a * b;<br />

if (b != 0) r<strong>et</strong>urn 0;<br />

*q = a / b;<br />

r<strong>et</strong>urn 1;<br />

}<br />

int main( ) {<br />

int u, v, x;<br />

x = 3;<br />

if (ProdQuot(x,2,&u,&v) == 0) {<br />

printf("%d x 2 = %d\n", x, u);<br />

}<br />

else {<br />

printf("%d x 2 = %d <strong>et</strong> %d / 2 =<br />

%d\n",x,u,x,v);<br />

}<br />

r<strong>et</strong>urn 0;<br />

}<br />

M. <strong>Deloizy</strong> Informatique - Généralités 89<br />

Fonctions réentrantes<br />

• Fonction exécutée plusieurs fois simultanément<br />

→ appelée <strong>de</strong> nouveau pendant son exécution<br />

– Systèmes multi-tâches<br />

– Interruptions<br />

• Contrainte :<br />

– Pas <strong>de</strong> donnée statique<br />

– Utilisation <strong>de</strong> données dynamiques<br />

→ Nouvelles données à chaque déclaration<br />

→ Données propres à chaque appel <strong>de</strong> fonction<br />

M. <strong>Deloizy</strong> Informatique - Généralités 90<br />

Fonctions récursives<br />

• Fonction qui se rappelle elle-même<br />

• L'appel peut être direct ou non<br />

• Particularités :<br />

– Fonctions réentrantes<br />

– Un point <strong>de</strong> sortie doit être prévu<br />

• Intérêt :<br />

– Écriture con<strong>de</strong>nsée <strong>et</strong> rapi<strong>de</strong> <strong>de</strong> programmes<br />

• Inconvénients :<br />

– Peu efficace à l'exécution<br />

– Gourmand en ressources<br />

M. <strong>Deloizy</strong> Informatique - Généralités 91<br />

<strong>Langage</strong> C<br />

M. <strong>Deloizy</strong> Informatique - Généralités 92<br />

23


Histoire<br />

<strong>Langage</strong> C<br />

C ANSI<br />

Brian KERNIGHAN & Dennis RITCHIE<br />

! Principes issus du BCPL <strong>et</strong> du B (1970)<br />

→ premier système UNIX<br />

! 1978 : Parution du livre "Le langage C"<br />

! Souvent associé à UNIX (écrit(<br />

en C)<br />

! Lié à aucune machine<br />

Lié à aucun système d'exploitation<br />

! 1988 : C norme ANSI<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C 1<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

2<br />

Intérêt du langage<br />

! <strong>Langage</strong> non spécifique (généraliste)<br />

! Bonne portabilité<br />

! Bonne efficacité (peu <strong>de</strong> sur-co<strong>de</strong><br />

co<strong>de</strong>)<br />

! Base du C++ (obj<strong>et</strong>)<br />

Constitution d’un<br />

programme C<br />

Programme<br />

Module<br />

1<br />

Module<br />

2<br />

Module<br />

Fonction1( ) {<br />

...<br />

}<br />

Module<br />

n<br />

Fichier .c<br />

(texte)<br />

Fonction1( ) {<br />

...<br />

}<br />

main( ) {<br />

...<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

3<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

4<br />

1


Syntaxe<br />

Mots clés<br />

! Commentaires.<br />

! /* Ceci est un commentaire */<br />

! Noms <strong>de</strong> symboles.<br />

! Symboles autorisés :<br />

! toto Toto<br />

t123<br />

_tx_<br />

_12 ___<br />

! Symboles non autorisés :<br />

! 12_ 2t<br />

été m% bon jour<br />

! Minuscules <strong>et</strong> majuscules.<br />

! Les minuscules <strong>et</strong> majuscules sont différenciés en C.<br />

a<br />

auto<br />

continue<br />

enum<br />

if<br />

short<br />

switch<br />

volatile<br />

break<br />

<strong>de</strong>fault<br />

extern<br />

int<br />

signed<br />

type<strong>de</strong>f<br />

while<br />

case<br />

do<br />

float<br />

long<br />

sizeof<br />

union<br />

char<br />

double<br />

for<br />

register<br />

static<br />

unsigned<br />

const<br />

else<br />

goto<br />

r<strong>et</strong>urn<br />

struct<br />

void<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

5<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

6<br />

! Les types <strong>de</strong> base<br />

! char :<br />

Types <strong>de</strong> variables<br />

! Caractères (8 bits).<br />

! Entier court (signé par défaut).<br />

! Type <strong>de</strong> données <strong>de</strong> taille élémentaire.<br />

! int :<br />

! Entier (signé par défaut).<br />

! Type pris par défaut.<br />

! Au moins 16 bits.<br />

! float :<br />

! Nombre en virgule flottante.<br />

Types dérivés<br />

! unsigned char<br />

! signed char<br />

! unsigned int ou unsigned<br />

! short<br />

! unsigned short<br />

! long int ou long<br />

! unsigned long int ou unsigned long<br />

! double<br />

! long double<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

7<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

8<br />

2


Dynamique <strong>de</strong>s nombres<br />

ENTIERS<br />

Valeur minimale Valeur maximale<br />

8 bits signé -128<br />

127<br />

8 bits non signé 0 255<br />

16 bits signé -32768<br />

32767<br />

16 bits non signé 0 65535<br />

32 bits signé -22 147 483 648 2 147 483 647<br />

32 bits non signé 0 4 294 967 295<br />

VIRGULE<br />

FLOTTANTE<br />

Dynamique <strong>de</strong>s nombres<br />

Chiffres<br />

significatifs<br />

Exposant<br />

min/max<br />

4 oct<strong>et</strong>s 7 ±38<br />

8 oct<strong>et</strong>s 15 ± 308<br />

10 oct<strong>et</strong>s 19 ± 4932<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

9<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

10<br />

Taille <strong>de</strong>s données<br />

! Si E représente l’encombrement mémoire d’un type :<br />

E(char) ≤ E(short) ≤ E(int<br />

int) ≤ E(long)<br />

E(float<br />

float) ≤ E(double) ≤ E(long double)<br />

! Opérateur sizeof.<br />

! Pas <strong>de</strong> type booléen.<br />

Résultat nul ⇒ faux<br />

Résultat non nul ⇒ vrai<br />

Types composés<br />

! les tableaux<br />

! les structures<br />

! les unions<br />

! Remarque :<br />

! On peut combiner les structures <strong>et</strong> les tableaux<br />

! " tableaux <strong>de</strong> structures<br />

! " structures contenant <strong>de</strong>s tableaux.<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

11<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

12<br />

3


Autres types<br />

! les types définis par le programmeur<br />

! type<strong>de</strong>f<br />

! void<br />

! type<strong>de</strong>f unsigned char byte;<br />

! type<strong>de</strong>f unsigned short word;<br />

! type<strong>de</strong>f unsigned long dword;<br />

Déclaration <strong>de</strong>s variables<br />

! char x ;<br />

⇒ x est un caractère<br />

(sur 8 bits : [-128…+127])[<br />

! int i, j, k ; ⇒ i, j <strong>et</strong> k sont <strong>de</strong>s entiers<br />

(sur 16 bits : [-32768…+32767])[<br />

! unsigned arthur ; ⇒ arthur est un entier non signé<br />

(sur 16 bits : [0…+65535])<br />

! unsigned char oct<strong>et</strong> ; ⇒ oct<strong>et</strong> est un caractère non signé<br />

(sur 8 bits : [0…+255])<br />

! char tab[10] ; ⇒ tab est un tableau pouvant contenir<br />

10 caractères<br />

! double f[5][3] ; ⇒ f est un tableau <strong>de</strong> 5 lignes<br />

<strong>et</strong> 3 colonnes (15 x double)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

13<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

14<br />

Tableaux<br />

! Le premier élément d’un tableau est d’indice 0.<br />

! Rangement consécutif en mémoire (Ex. <strong>de</strong> tab[0] à<br />

tab[9])<br />

! Tableaux multi-dimensionnés<br />

: le <strong>de</strong>rnier indice « court »<br />

le plus vite :<br />

f[0][0], f[0][1], f[0][2], f[1][0], f[1][1], f[1][2], f[2][0], … , f[4][1], f[4][2]<br />

Constantes<br />

Types<br />

Écritures<br />

Exemples<br />

Caractère<br />

‘x’ ‘A’, ‘=’, ‘\\’,‘<br />

‘\’’‘<br />

Entier<br />

nnn ou ±nnn<br />

421, 0, -12, +456<br />

Entier exprimé en octal 0nnn ou ± 0nnn 0712, 010, -057<br />

Entier hexadécimal<br />

0xnn ou 0xNN<br />

0x4A, 0x00ff<br />

double<br />

± nnn.nn ou ± nnnE ± nn 1.0, -4., 3E4, 1.6e-19<br />

19<br />

Chaîne <strong>de</strong> caractères<br />

"xxxxxx"<br />

"Bonjour les amis"<br />

Remarque : \ est le caractère d‘échappement en C<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

15<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

16<br />

4


Constantes particulières<br />

Séquence<br />

Signification<br />

\r R<strong>et</strong>our chariot (en début <strong>de</strong> ligne).<br />

\n Saut à la ligne suivante. 0x0A<br />

\t Tabulation. 0x09<br />

\\ Caractère \<br />

\’ Caractère '<br />

\" Caractère "<br />

\xnn<br />

\ooo<br />

Exemple<br />

printf("<br />

("\rbonjour")<br />

printf("bonjour<br />

("bonjour\n") n")<br />

printf("Rés.<br />

("Rés.\tMoy.\n")<br />

Nombre hexadécimal<br />

Nombre octal (o : digit octal) \012,<br />

Résultat<br />

") bonjour<br />

bonjour!<br />

Rés.<br />

Moy. !<br />

printf("valeur : \\10\\\n")<br />

valeur : \10\!<br />

x='\''<br />

''-0x20<br />

x=39-32<br />

32 ⇒ x=7<br />

printf("Il dit : \"Bof!\"\n")<br />

Il dit : "Bof!" <br />

0x3B, 0xFA8 59, 4008<br />

012, \033<br />

10, 27<br />

Suffixe :<br />

Entier<br />

Virgule flottante<br />

Suffixes<br />

sans<br />

U ou u<br />

L ou l<br />

int<br />

unsigned int<br />

long<br />

double - long double<br />

! Exemples :<br />

12L :<br />

valeur 12 codée sur un type long<br />

40000u : codé sur un type unsigned int<br />

13.4 : constante double<br />

12.5f : constante float<br />

12UL :<br />

constante unsigned long int<br />

Applications :<br />

unsigned x = 120000UL*4/10000;<br />

long y = 15000L*4;<br />

F ou f<br />

float<br />

Float<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

17<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

18<br />

Organisation générale d’un module<br />

Déclarations<br />

…<br />

Fonction1<br />

…<br />

Fonction2<br />

…<br />

Définition d’une fonction<br />

! Déclaration :<br />

! du nom <strong>de</strong> la fonction,<br />

! du type <strong>de</strong> valeur r<strong>et</strong>ournée par la fonction<br />

! <strong>de</strong>s noms <strong>et</strong> <strong>de</strong>s types <strong>de</strong>s arguments transmis.<br />

! Corps <strong>de</strong> la fonction (entre accola<strong>de</strong>s) :<br />

! déclarations <strong>de</strong> données locales à la fonction<br />

! blocs d'instructions<br />

! r<strong>et</strong>our à la fonction appelante (avec un éventuel<br />

renvoi d'une valeur)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

19<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

20<br />

5


Exemple<br />

Ancienne syntaxe<br />

double somme(double a, double b)<br />

{<br />

double res;<br />

res = a + b;<br />

r<strong>et</strong>urn res;<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

21<br />

void init_glob( ( )<br />

{<br />

A=0;<br />

TOT=12E4;<br />

}<br />

double somme(a, b)<br />

double a, b;<br />

{<br />

double res;<br />

res = a + b;<br />

r<strong>et</strong>urn res;<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

22<br />

double somme(double a, double b)<br />

{<br />

double res;<br />

res = a + b;<br />

r<strong>et</strong>urn res;<br />

}<br />

! ‘;’ omis en fin <strong>de</strong> ligne <strong>de</strong> définition<br />

! Paramètres transmis par valeur<br />

void init_glob()<br />

{<br />

A=0;<br />

TOT=12E4;<br />

}<br />

Fonction ne renvoie rien → void<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

23<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

24<br />

6


somme(int<br />

a, int b)<br />

{<br />

int s;<br />

s=a+b;<br />

r<strong>et</strong>urn s;<br />

}<br />

Type <strong>de</strong> la fonction est omis → int<br />

double pi(void<br />

void)<br />

{<br />

double x;<br />

x=atan<br />

atan(1.0)*4;<br />

r<strong>et</strong>urn x;<br />

}<br />

Fonction non déclarée → int<br />

Ici : inclure math.h<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

25<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

26<br />

Prototype<br />

! Perm<strong>et</strong> d'indiquer :<br />

! le type <strong>de</strong> donnée r<strong>et</strong>ourné par une fonction<br />

! le nombre <strong>et</strong> le type <strong>de</strong>s arguments transmis.<br />

# Déclaration <strong>de</strong> fonction.<br />

Exemples <strong>de</strong> prototype :<br />

double sin(double);<br />

double somme(double a, double b);<br />

Blocs d’instructions<br />

! Constitué :<br />

! d'une instruction élémentaire terminée par un<br />

caractère ";"<br />

ou<br />

! d'un ensemble d'instructions élémentaires encadrées<br />

par <strong>de</strong>s accola<strong>de</strong>s ; dans ce cas, le bloc d'instructions<br />

peut comporter <strong>de</strong>s déclarations (locales à ce bloc).<br />

ou<br />

! d'un simple caractère ';'.'<br />

'. Dans ce cas, l'instruction est<br />

vi<strong>de</strong> (sans eff<strong>et</strong>).<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

27<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

28<br />

7


x = 2*a + b;<br />

ou :<br />

{<br />

x = 2;<br />

y = 4;<br />

z = x+y;<br />

}<br />

ou :<br />

{<br />

int i;<br />

i = 3;<br />

x = 2*(i++);<br />

y=i;<br />

}<br />

Exemples<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

29<br />

Opérateur<br />

*<br />

/<br />

+<br />

-<br />

%<br />

^<br />

|<br />

&<br />

><br />

Opérateurs arithmétiques<br />

Description<br />

multiplication<br />

division<br />

addition<br />

soustraction<br />

modulo (reste <strong>de</strong> la division entière)<br />

ou exclusif (opération sur les bits)<br />

ou (opération sur les bits)<br />

<strong>et</strong> (opération sur les bits)<br />

décalage à gauche<br />

décalage à droite<br />

Exemple (a=5, b=3, c=1)<br />

x = 20*a x = 100<br />

z = 10.0/4 z = 2.5<br />

x = 3+b x = 6<br />

x = 3-b x = 0<br />

x = 8%a x = 3<br />

x = a^b x = 6<br />

x = a|b x = 7<br />

x = a&b x = 1<br />

x = ac x = 1<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

30<br />

Opérateurs logiques<br />

Opérateurs d’affectation<br />

Opérateur<br />

==<br />

||<br />

&&<br />

!=<br />

<<br />

><br />

=<br />

Description<br />

test d'égalité<br />

ou logique<br />

<strong>et</strong> logique<br />

différent<br />

inférieur<br />

supérieur<br />

inférieur ou égal<br />

supérieur ou égal<br />

Exemple (a=5, b=3)<br />

x = a==b x = 0<br />

x = (a==1)||(a==2) x = 0<br />

x = (a>0) && (a …<br />

Exemple (a=5, b=3, c=1)<br />

x = a<br />

⇒ x = 5<br />

a += 1<br />

⇒ a = 6<br />

a -= b<br />

⇒ a = 2<br />

a /= b-c<br />

⇒ a = 2<br />

a *= 8<br />

⇒ a = 40<br />

a %= b<br />

⇒ a = 2<br />

a ^= b<br />

⇒ a = 6<br />

a |= b<br />

⇒ a = 7<br />

a &= b<br />

⇒ a = 1<br />

a = b-2<br />

⇒ a = 2<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

31<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

32<br />

8


Écritures possibles<br />

Opérateur ternaire<br />

! x = (a=3)+1;<br />

m<strong>et</strong> 3 dans a <strong>et</strong> 4 dans x<br />

! x -= = (a+=10); augmente a <strong>de</strong> 10 <strong>et</strong> soustrait le résultat <strong>de</strong> x<br />

! x = y = 2;<br />

m<strong>et</strong> 2 dans y puis y dans x<br />

! x = a+=2;<br />

ajoute 2 à a, puis m<strong>et</strong> le résultat dans x<br />

Opérateur<br />

?:<br />

Description<br />

choix d'une valeur selon une<br />

condition<br />

si la condition est vraie, la<br />

première expression est<br />

r<strong>et</strong>ournée, sinon, la<br />

<strong>de</strong>uxième expression est<br />

r<strong>et</strong>ournée.<br />

Exemple (a=5, b=3, c=1)<br />

x=(a>4)?(b*2):(c+1) ⇒ x = 6<br />

x=(a3)<br />

x = a++<br />

x = ++a<br />

⇒ x = -5<br />

⇒ x = 5<br />

⇒ x = -6(0xFA)<br />

⇒ x = 0<br />

⇒ x = 5, a = 6<br />

⇒ x = 6, a = 6<br />

--<br />

auto décrémentation (post ou pré)<br />

x = a—<br />

x = --a<br />

⇒ x = 5, a = 4<br />

⇒ x = 4, a = 4<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

35<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

36<br />

9


Sizeof & Cast<br />

Expressions<br />

Opérateur<br />

sizeof<br />

(type)<br />

Description<br />

donne la taille d'un obj<strong>et</strong> (donnée ou type).<br />

est équivalent à une constante, déterminée par le compilateur.<br />

•sizeof(char) vaut 1<br />

•sizeof<br />

sur un tableau donne le nombre d'oct<strong>et</strong>s occupé par le<br />

tableau<br />

•sizeof(int)) vaut 2 si le type int est codé sur 16 bits<br />

opérateur cast (transtypage). Perm<strong>et</strong> <strong>de</strong> modifier le type d'une<br />

expression ; type représente un type <strong>de</strong> donnée prédéfini.<br />

Exemples :<br />

i = (int(<br />

int)(100.0*sin(2.45));<br />

x = (double)(2*a+1);<br />

! Utilisent <strong>de</strong>s opérateurs selon leur priorité<br />

Exemple :<br />

x = 2*a + 3*b/4/c; $<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

37<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

38<br />

Priorités<br />

Opérateurs<br />

Priorité<br />

() [] -> .<br />

15<br />

! ~ ++ -- + * - * * * & * (type) sizeof<br />

14<br />

* / %<br />

13<br />

+ -<br />

12<br />

><br />

11<br />

< >=<br />

10<br />

== !=<br />

9<br />

&<br />

8<br />

^<br />

7<br />

|<br />

6<br />

&&<br />

5<br />

||<br />

4<br />

?:<br />

3<br />

= += -= *= /= %= &= ^= |= =<br />

2<br />

,<br />

1<br />

(*) : Opérateurs unaires & pointeurs<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

39<br />

Structures conditionnelles<br />

Tests si … sinon …<br />

if (condition)<br />

bloc d'instructions à exécuter si la condition est vraie<br />

else<br />

bloc d'instructions à exécuter si la condition est fausse<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

40<br />

10


Structure itérative tant que<br />

Structure itérative faire … tant que<br />

Boucles tant que … faire :<br />

Boucles faire … tant que :<br />

while (condition)<br />

bloc d'instructions à exécuter si la condition est vraie.<br />

Exemple :<br />

while(x


Exemple :<br />

do<br />

{<br />

k = g<strong>et</strong>char( ( ); /* Acquisition clavier -> > k */<br />

switch (k) /* Test <strong>de</strong> k */<br />

{<br />

case '1':<br />

menu1( ); /* Appeler menu1 si '1' tapé */<br />

break;<br />

/* Quitter switch */<br />

case '2':<br />

menu2( ); /* Appeler menu1 si '2' tapé */<br />

break;<br />

/* Quitter switch */<br />

case 'q':<br />

case 'Q':<br />

printf("Fin du programme.\n");<br />

/* Quitter le programme si */<br />

exit(0); /* 'q' ou 'Q' tapé */<br />

<strong>de</strong>fault:<br />

printf("?????<br />

("?????\n");<br />

/* Erreur */<br />

}<br />

}<br />

while((k=='1') || (k=='2'));<br />

Rupture <strong>de</strong> séquence break<br />

Sortir d'une boucle :<br />

! while …<br />

! do … while<br />

! for<br />

! switch … case<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

45<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

46<br />

Rupture <strong>de</strong> séquence continue<br />

Interrompre le déroulement d'une boucle<br />

! while …<br />

! do … while<br />

! for<br />

→ directement à la fin du bloc d'instructions<br />

Exemple<br />

for(i=0; i


Branchements inconditionnels<br />

Jamais utilisés<br />

Portée <strong>de</strong>s données<br />

Exemple :<br />

...<br />

x = 3+i;<br />

if (x


Donnée locale à une fonction<br />

void fonction(int<br />

int a, double x) a <strong>et</strong> x sont <strong>de</strong>s variables locales à la fonction<br />

{<br />

unsigned c,d;<br />

...<br />

}<br />

c <strong>et</strong> d sont <strong>de</strong>s variables locales à la fonction<br />

Donnée locale à un bloc<br />

d’instructions<br />

void fonction(int<br />

int a, double x) a <strong>et</strong> x sont <strong>de</strong>s variables locales à la fonction<br />

{<br />

unsigned i; i est locale à la fonction<br />

...<br />

for(i=0; i


Exemple<br />

Allocation dynamique<br />

Exemple :<br />

void fonction(void<br />

void)<br />

{<br />

static x; x est <strong>de</strong> type int ; vaut 0 au démarrage du programme.<br />

static long double pi=3.14L;<br />

pi vaut 3.14 au démarrage du programme<br />

if(x


Données volatiles<br />

volatile<br />

Donnée dont le contenu est susceptible d’être modifié<br />

« tout seul ».<br />

⇒ Pas d’optimisation.<br />

Exemple :<br />

...<br />

volatile char x;<br />

extern volatile unsigned char pio;<br />

...<br />

Pointeurs<br />

Accès aux données à partir <strong>de</strong> leur adresse<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

61<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

62<br />

Notation :<br />

où<br />

<strong>et</strong><br />

nom_var<br />

*nom_var<br />

*nom_var<br />

Déclaration :<br />

nom_type *nom_var;<br />

Exemple :<br />

char *c;<br />

Déclaration<br />

représente la variable pointeur (qui contient une adresse)<br />

représente la variable pointée.<br />

c contient l'adresse <strong>de</strong> la variable pointée<br />

la variable pointée est <strong>de</strong> type char<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

63<br />

Pointeurs <strong>et</strong> constantes<br />

pointeur sur une chaîne <strong>de</strong> caractères constante :<br />

"chaîne <strong>de</strong> caractères"<br />

pointeur sur une donnée constante :<br />

const char *c; (*c est constant)<br />

pointeur constant :<br />

double * const v; (v est constant)<br />

pointeur constant sur une donnée constante :<br />

const int * const p; (p <strong>et</strong> *p sont constants)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

64<br />

16


Arithmétique <strong>de</strong>s pointeurs<br />

Pointeurs <strong>et</strong> tableaux<br />

Opérations vali<strong>de</strong>s<br />

pointeur<br />

pointeur<br />

pointeur<br />

pointeur<br />

Opérateur<br />

+<br />

-<br />

-<br />

comparaison<br />

entier<br />

entier<br />

pointeur<br />

pointeur<br />

Résultat<br />

Pointeur<br />

Entier<br />

…<br />

p+i accès au<br />

p pointeur<br />

i entier<br />

élément situé à partir <strong>de</strong> p<br />

accès au i ème élément situé à partir <strong>de</strong><br />

⇒ fonctionnement i<strong>de</strong>ntique aux tableaux<br />

p-2<br />

p-1<br />

p p+1 p+2 …<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

65<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

66<br />

Parcours d’une chaîne <strong>de</strong> caractères<br />

char *p, c;<br />

p = "HELLO";<br />

c = *p; ⇒ c = 'H'<br />

c = *(p+1);<br />

p += 4;<br />

p--; ⇒ *p = 'L'<br />

⇒ c = 'E'<br />

⇒ *p = 'O'<br />

Types <strong>de</strong>s données pointées<br />

Pointeur ± entier ⇒ Valeur du pointeur ± n fois la taille <strong>de</strong> l'élément pointé.<br />

Exemple :<br />

char *pc ; pc pointe sur un caractère (taille : 1 oct<strong>et</strong>)<br />

int *pi ; pi pointe sur un entier (taille : 4 oct<strong>et</strong>s ici)<br />

....<br />

On suppose que pc=0x3AB0 <strong>et</strong> pi=0xE020<br />

pc+1 ; → vaut 0x3AB1<br />

pc+5 ; → vaut 0x3AB5<br />

pi+1 ; → vaut 0xE024<br />

pi+5 ; → vaut 0xE034<br />

⇒ nécessité <strong>de</strong> connaître le type <strong>de</strong> la donnée pointée<br />

l'arithmétique <strong>de</strong>s pointeurs ne fonctionne pas avec <strong>de</strong>s pointeurs void<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

67<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

68<br />

17


Utilité <strong>de</strong>s pointeurs<br />

! accé<strong>de</strong>r aux éléments d'un tableau<br />

! manipuler les chaînes <strong>de</strong> caractères<br />

! perm<strong>et</strong>tre aux fonctions <strong>de</strong> r<strong>et</strong>ourner plusieurs<br />

valeurs<br />

Tableaux<br />

Données <strong>de</strong> même type disposées <strong>de</strong> manière contiguë en<br />

mémoire.<br />

Exemple :<br />

double v[5];<br />

→ place 5 variables en virgule flottante à partir <strong>de</strong><br />

l'adresse v.<br />

! v est un pointeur constant → adresse <strong>de</strong> la première donnée<br />

du tableau.<br />

! v[i] perm<strong>et</strong> d’accé<strong>de</strong>r au i ème élément du tableau (i entier).<br />

! Le premier élément d'un tableau est toujours d’indice 0.<br />

Exemple : v[0] à v[4].<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

69<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

70<br />

Accès aux éléments <strong>de</strong>s tableaux<br />

v pointeur ⇒ accès à l'élément i du tableau :<br />

*(v+i).<br />

⇒ Les notations v[i] <strong>et</strong> *(v+i) sont équivalentes<br />

Elles peuvent être utilisées même lorsque v n'est pas un<br />

tableau<br />

Sizeof <strong>et</strong> tableaux<br />

sizeof appliqué sur un tableau<br />

⇒ espace mémoire occupé par le tableau.<br />

Exemple :<br />

double v[5] → sizeof(v) vaut 40<br />

(si le type double a une taille <strong>de</strong> 8)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

71<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

72<br />

18


Sizeof <strong>et</strong> pointeurs<br />

sizeof(v)/<br />

(v)/sizeof(*v)<br />

indique le nombre d'éléments que peut contenir un tableau.<br />

!!! % sizeof appliqué à un pointeur donne<br />

la taille du pointeur.<br />

Exemple :<br />

char *str*<br />

= "Hello"; ⇒ sizeof(str<br />

str) ) donne 2<br />

(si pointeurs sur 2 oct<strong>et</strong>s)<br />

char str[10] = "Hello"; ⇒ sizeof(str<br />

str) ) donne 10<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

73<br />

Chaînes <strong>de</strong> caractères<br />

Chaînes <strong>de</strong> caractères<br />

→ tableaux <strong>de</strong> caractères.<br />

→ '\0' est le délimiteur <strong>de</strong> chaîne.<br />

notée entre guillem<strong>et</strong>s.<br />

Exemple : "Bonjour à tous"<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

74<br />

Fonctions <strong>et</strong> pointeurs<br />

<strong>Langage</strong> C ⇒ Transmission <strong>de</strong>s paramètres par valeurs.<br />

Transmission par référence → utilisation <strong>de</strong> pointeurs<br />

Exemple 1<br />

Fonction initialisant un tableau à 0 :<br />

void InitTab(int<br />

int *baseTab, unsigned nb)<br />

{<br />

unsigned i;<br />

for(i=0; i


Exemple 2<br />

Autre écriture possible <strong>de</strong> InitTab :<br />

void InitTab(int<br />

int *baseTab, unsigned nb)<br />

{<br />

while(nb<br />

(nb--)) *(baseTab<br />

baseTab++)=0;<br />

}<br />

Exemple 3<br />

Recherche <strong>de</strong> minimum <strong>et</strong> maximum :<br />

void MinMax(double x, double *Min, double *Max)<br />

{<br />

if(x < *Min) *Min*<br />

= x;<br />

else if(x > *Max) *Max*<br />

= x;<br />

}<br />

...<br />

double tab[100];<br />

unsigned i;<br />

double mini, maxi;<br />

...<br />

mini = maxi = *tab;<br />

for(i=1; i


Opérations sur les flux<br />

! « Ouverture »<br />

→ création du buffer<br />

→ création du lien avec le dispositif physique (FILE *)<br />

→ FILE* fopen(char *NomFichier*<br />

NomFichier, , char *Mo<strong>de</strong>)<br />

! Opérations d’entrées/sorties<br />

→ Entrées/sorties séquentielles<br />

→ Opérations binaires ou formatées<br />

→ Gestion du flux (positionnement, mise à jour buffer…)<br />

Utilisation <strong>de</strong>s flux<br />

Nécessite l’utilisation <strong>de</strong> <br />

Remarque :<br />

Opérations sur les flux peuvent échouer (disque plein, fichier<br />

introuvable…)<br />

→ Nécessiter <strong>de</strong> vérifier validité opérations<br />

→ Tester les co<strong>de</strong>s d’erreurs (EOF ou NULL).<br />

! « Ferm<strong>et</strong>ure »<br />

→ mise à jour <strong>de</strong>s données contenues dans le buffer<br />

→ <strong>de</strong>struction du buffer<br />

→ int fclose(FILE *f)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

81<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

82<br />

Flux en sortie<br />

Flux en entrée<br />

! Accès en écriture <strong>de</strong>s fichiers.<br />

! Par défaut l’écran (stdout(<br />

tdout) → ne nécessite pas d’ouverture.<br />

! Fonctions <strong>de</strong> gestion du flux :<br />

! printf, fprintf, sprintf,…<br />

int printf(const<br />

char *format, …)<br />

int fprintf(FILE *f, const char *format, …)<br />

int sprintf(char *str*<br />

str, const char *format, …)<br />

! putchar, putc, fputc<br />

int putchar(int<br />

x)<br />

int putc(int<br />

x, FILE *f)<br />

int fputc(int<br />

x, FILE *f)<br />

! puts, fputs<br />

char *puts(const char *str)<br />

char *fputs(const char *str, FILE *f)<br />

! fwrite<br />

int fwrite(const<br />

void *buffer, size_t size, size_t nb, , FILE *f)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

83<br />

! Accès en lecture <strong>de</strong>s fichiers.<br />

! Par défaut le clavier (stdin(<br />

stdin) → ne nécessite pas d’ouverture.<br />

! Fonctions <strong>de</strong> gestion du flux :<br />

! scanf, fscanf, sscanf,…<br />

int scanf(const<br />

const char *format,…)<br />

int fscanf(FILE *f, const char *format,…)<br />

int sscanf(char *s, const char *format,…)<br />

! g<strong>et</strong>char, g<strong>et</strong>c, fg<strong>et</strong>c<br />

int g<strong>et</strong>char(void<br />

void)<br />

int g<strong>et</strong>c(FILE *f)<br />

int fg<strong>et</strong>c(FILE *f)<br />

! g<strong>et</strong>s, fg<strong>et</strong>s<br />

char *g<strong>et</strong>s(void)<br />

char *fg<strong>et</strong>s(char *<strong>de</strong>st, size_t nb_max, FILE *f)<br />

! fread<br />

int fread(void<br />

*buffer, size_t size, size_t nb, , FILE *f)<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

84<br />

21


Gestion <strong>de</strong>s flux<br />

! long ftell(FILE *f)<br />

! int fseek(FILE *f, long offs<strong>et</strong>, int fromwhere)<br />

! void rewind(FILE *f)<br />

! int feof(FILE *f)<br />

! int fflush(FILE *f)<br />

Entrées sorties formatées<br />

Spécifications <strong>de</strong> format (pour printf <strong>et</strong> scanf) ) :<br />

% [flags[<br />

flags] ] [width[<br />

width] ] [.prec<br />

prec] ] [F|N|h|l] type<br />

Type Format <strong>de</strong> la sortie<br />

d : entier décimal signé<br />

i : entier décimal signé<br />

o : entier octal non signé<br />

u : entier décimal non signé<br />

x : avec printf = entier hexadécimal non signé en minuscules<br />

: avec scanf = entier hexadécimal<br />

X : avec printf = entier hexadécimal non signé en majuscules<br />

: avec scanf = entier hexadécimal long<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

85<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

86<br />

Spécifications <strong>de</strong> format (pour printf <strong>et</strong> scanf) ) :<br />

% [flags[<br />

flags] ] [width[<br />

width] ] [.prec<br />

prec] ] [F|N|h|l] type<br />

Type Format <strong>de</strong> la sortie<br />

f : virgule flottante [-]dddd.ddd[<br />

e : virgule flottante avec exposant [-]d.ddd[<br />

e [+/-]ddd<br />

g : format e ou f suivant la précision<br />

E : comme e mais l'exposant est la l<strong>et</strong>tre E<br />

G : comme g mais l'exposant est la l<strong>et</strong>tre E<br />

c : caractère simple<br />

s : affiche les caractères jusqu'au caractère nul ou jusqu'à ce que e la précision soit<br />

atteinte<br />

% : caractère <strong>de</strong> pourcentage %<br />

p : pointeur<br />

n : range (à l'adresse pointée par l'argument d'entrée) le nombre <strong>de</strong> caractères<br />

écrits.<br />

Spécifications <strong>de</strong> format (pour printf <strong>et</strong> scanf) ) :<br />

% [flags[<br />

flags] ] [width[<br />

width] ] [.prec<br />

prec] ] [F|N|h|l] type<br />

[flags] Signification<br />

aucun<br />

: résultat justifié à droite <strong>et</strong> complété à gauche par <strong>de</strong>s espaces s ou <strong>de</strong>s 0<br />

- : résultat justifié à gauche <strong>et</strong> complété à droite par <strong>de</strong>s espaces<br />

+ : les résultats commencent toujours par le signe + ou -<br />

espace<br />

: n'affiche le signe que pour les valeurs négatives<br />

# l'argument doit être converti en utilisant une autre forme :<br />

c,s,d,i,u<br />

: sans eff<strong>et</strong><br />

o : 0 sera placé <strong>de</strong>vant l'argument s'il est non nul<br />

x ou X<br />

: 0x ou 0X placé <strong>de</strong>vant la valeur <strong>de</strong> l'argument<br />

e, E, f : le résultat contiendra toujours un point décimal<br />

g or G<br />

: même chose mais sans les zéros à droite<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

87<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

88<br />

22


Spécifications <strong>de</strong> format (pour printf <strong>et</strong> scanf) ) :<br />

% [flags[<br />

flags] ] [width[<br />

width] ] [.prec<br />

prec] ] [F|N|h|l] type<br />

[width] Eff<strong>et</strong> sur l'affichage<br />

n : affichage d'au moins n caractères, au besoin complété par<br />

<strong>de</strong>s espaces<br />

0n<br />

: affichage d'au moins n caractères, au besoin complété à<br />

gauche par <strong>de</strong>s chiffres 0<br />

* : l'argument suivant <strong>de</strong> la liste contient la spécification <strong>de</strong><br />

largeur<br />

Spécifications <strong>de</strong> format (pour printf <strong>et</strong> scanf) ) :<br />

% [flags[<br />

flags] ] [width[<br />

width] ] [.prec<br />

prec] ] [F|N|h|l] type<br />

[.prec<br />

prec] Eff<strong>et</strong> sur l'affichage<br />

aucun<br />

: précision par défaut<br />

.0 : avec d,i,o,u,x précision par défaut<br />

: avec e, E, f pas <strong>de</strong> point décimal<br />

.n : n caractères au plus<br />

* : l'argument suivant <strong>de</strong> la liste contient la précision<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

89<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

90<br />

Spécifications <strong>de</strong> format (pour printf <strong>et</strong> scanf) ) :<br />

% [flags[<br />

flags] ] [width[<br />

width] ] [.prec<br />

prec] ] [F|N|h|l[<br />

F|N|h|l] ] type<br />

Modificateur Comment arg est interprété<br />

F : arg est interprété comme un pointeur long<br />

N : arg est interprété comme un pointeur court<br />

h : arg est interprété comme un entier <strong>de</strong> type short pour<br />

d,i,o,u,x,X<br />

l : arg est interprété comme un entier <strong>de</strong> type long pour<br />

d,i,o,u,x,X<br />

l : arg est interprété comme un réel <strong>de</strong> type double pour<br />

e,E,f,g,G (scanf(<br />

scanf)<br />

L : arg est interprété comme un réel <strong>de</strong> type long double<br />

pour e,E,f,g,G<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

91<br />

Copie <strong>de</strong> fichier texte<br />

#inclu<strong>de</strong><br />

<br />

#inclu<strong>de</strong><br />

<br />

#inclu<strong>de</strong><br />

<br />

void erreur(int<br />

err, const char *fmt*<br />

fmt, , ...)<br />

{<br />

va_list arg;<br />

va_start(arg<br />

arg,fmt);<br />

fprintf(st<strong>de</strong>rr<br />

st<strong>de</strong>rr,"Erreur [%d] : ",err<br />

err);<br />

vfprintf(st<strong>de</strong>rr<br />

st<strong>de</strong>rr,fmt,arg);<br />

va_end(arg<br />

arg);<br />

exit(err<br />

err);<br />

}<br />

main(int<br />

int argc, , char *argv*<br />

argv[])<br />

{<br />

FILE *fs*<br />

fs, , *fd*<br />

;<br />

int x ;<br />

if(argc<br />

argc>1)<br />

{<br />

fs=fopen<br />

fopen(argv[1],"r");<br />

if(fs<br />

fs==NULL)<br />

erreur(1,"Le fichier %s ne peut être<br />

ouvert.\n",<br />

n",argv[1]);<br />

}<br />

else fs=stdin<br />

stdin;<br />

if(argc<br />

argc>2)<br />

{<br />

fd=fopen<br />

fopen(argv[2],"w");<br />

if(fd<br />

fd==NULL)<br />

erreur(2,"Création <strong>de</strong> %s<br />

impossible.\n",<br />

n",argv[1]);<br />

}<br />

else fd=stdout<br />

stdout;<br />

while((x=<br />

((x=g<strong>et</strong>c(fs))!=EOF)<br />

if(putc<br />

putc(x, (x,fd)==EOF) erreur(3,"Erreur<br />

en écriture");<br />

fclose(fd<br />

fd);<br />

fclose(fs<br />

fs);<br />

r<strong>et</strong>urn 0;<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

92<br />

23


Fonctions standard<br />

Manipulation <strong>de</strong> chaînes <strong>de</strong><br />

caractères <br />

memchr<br />

strcat<br />

strchr<br />

strrstr<br />

Définies par le C<br />

memcmp<br />

memcpy<br />

strncat<br />

strcpy<br />

strrchr<br />

strspn<br />

strlen<br />

strerror<br />

memmove<br />

strncpy<br />

strcspn<br />

mems<strong>et</strong><br />

strcmp<br />

strpbrk<br />

strncmp<br />

strtok<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

93<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

94<br />

Entrées sorties <br />

clearerr<br />

fclose<br />

fcloseall<br />

fdopen<br />

feof<br />

ferror<br />

fflush<br />

fg<strong>et</strong>c<br />

fg<strong>et</strong>char<br />

fg<strong>et</strong>pos<br />

fg<strong>et</strong>s<br />

fileno<br />

ftell<br />

g<strong>et</strong>c<br />

g<strong>et</strong>char<br />

g<strong>et</strong>s<br />

g<strong>et</strong>w<br />

perror<br />

printf<br />

putcs<br />

putchar<br />

puts<br />

tmpfile<br />

tmpnam<br />

ung<strong>et</strong>c<br />

unlink<br />

fwrite<br />

flushall<br />

fopen<br />

fprintf<br />

fputc<br />

fputchar<br />

fputs<br />

fread<br />

freopen<br />

fscanf<br />

fseek<br />

fs<strong>et</strong>pos<br />

putw<br />

remove<br />

vfprintf<br />

rewind<br />

scanf<br />

s<strong>et</strong>buf<br />

s<strong>et</strong>vbuf<br />

sprintf<br />

scanf<br />

_strerror<br />

strerror<br />

vfscanf<br />

vprintf<br />

vscanf<br />

vsprintf<br />

vsscanf<br />

rename<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

95<br />

Fonctions utilitaires <br />

atof<br />

atoi<br />

atol<br />

strtod<br />

strtol<br />

strtoul<br />

rand<br />

srand<br />

bsearch<br />

qsort<br />

calloc<br />

malloc<br />

realloc<br />

free<br />

abort<br />

exit<br />

atexit<br />

system<br />

g<strong>et</strong>env<br />

abs<br />

labs<br />

ldiv<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

96<br />

div<br />

24


Structures<br />

→ Agglomérats <strong>de</strong> données<br />

! Exemple :<br />

! Un individu :<br />

! Nom – Age – Profession – Poids<br />

& Ensemble <strong>de</strong> données propres à chaque individu<br />

& Informations rangées dans une variable unique (pour<br />

chaque individu)<br />

→ Champs <strong>de</strong> la structure<br />

Déclaration <strong>de</strong>s structures<br />

Déclaration :<br />

struct [TypeStructure]<br />

{<br />

TypeVar1 var1;<br />

TypeVar2 var2;<br />

…<br />

} [NomStruct1][,NomStruct2][,…] ;<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

97<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

98<br />

Utilisation <strong>de</strong>s structures<br />

Exemple <strong>de</strong> déclaration :<br />

struct TIndividu<br />

{<br />

char Nom[40];<br />

unsigned age;<br />

char Profession[80];<br />

float Poids;<br />

};<br />

struct TIndividu Marcel, Maurice;<br />

Utilisation :<br />

Chaque champ <strong>de</strong> la structure est utilisable comme une<br />

variable ordinaire (<strong>de</strong> type défini lors <strong>de</strong> la<br />

déclaration <strong>de</strong> la structure).<br />

On utilise la notation :<br />

.<br />

Exemples :<br />

scanf("%s",<br />

("%s",Marcel.Nom);<br />

Maurice.Age=32;<br />

Marcel.Poids=58.6;<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

99<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

100<br />

25


Types <strong>de</strong> données contenues<br />

Les données contenues dans une structure sont<br />

toutes celles autorisées par le langage C :<br />

! Types <strong>de</strong> base,…<br />

! Types utilisateurs<br />

! Structures<br />

! Tableaux<br />

! Pointeurs<br />

! …<br />

Exemple<br />

Exemple :<br />

struct<br />

{<br />

int ac;<br />

double t[10];<br />

struct { int a, ab, ac[3]; } si;<br />

}tv, tbv[10];<br />

…<br />

tv.t[4]=5;<br />

tv.ac=3;<br />

tv.si.ac[2]=0;<br />

tbv[0].<br />

[0].si.ac[0]=1;<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

101<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

102<br />

Structures <strong>et</strong> pointeurs<br />

Structure : donnée à fort encombrement mémoire<br />

→ Éviter la transmission par valeur lors d’un d<br />

appel <strong>de</strong> fonction<br />

→ Utilisation <strong>de</strong> pointeurs<br />

Exemple :<br />

void AcqParam(struct<br />

TIndividu *x);<br />

…<br />

struct TIndividu Marcel, Maurice, Groupe[30];<br />

AcqParam(&Marcel);<br />

AcqParam(Groupe+2); ou AcqParam(&(Groupe[2]));<br />

Pointeurs <strong>de</strong> structures<br />

Si x est un pointeur <strong>de</strong> structure, on accè<strong>de</strong><br />

à la variable<br />

pointée e par la notation :<br />

(*x). ou<br />

x -> <br />

Exemple :<br />

void AcqParam(struct<br />

TIndividu *x)<br />

{<br />

scanf("%s",(*x).nom);<br />

ou scanf("%s",x<br />

("%s",x->nom);<br />

scanf("%u",&(x<br />

("%u",&(x->age));<br />

x->Poids=60.0;<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

103<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

104<br />

26


Champs <strong>de</strong> bits<br />

→ Définition <strong>de</strong> données<br />

entières<br />

<strong>de</strong> p<strong>et</strong>ite taille (nombre <strong>de</strong><br />

bits indiqué)<br />

→ Utilisation : Indicateurs (flags(<br />

flags), programmation bas niveau<br />

Exemple :<br />

struct<br />

{<br />

unsigned CopyOnly:1;<br />

unsigned CaseDepend:1;<br />

unsigned Mo<strong>de</strong>:2;<br />

:4;<br />

int Rsv:8;<br />

}Options;<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

105<br />

Unions<br />

Déclaration & utilisation i<strong>de</strong>ntiques aux structures<br />

Mais<br />

Tous les champs sont situés à la même adresse<br />

Exemple : (pour examiner le codage d'un nombre<br />

double)<br />

union {<br />

double vd;<br />

unsigned char vb[sizeof<br />

sizeof(double)];<br />

}x;<br />

…<br />

x.vd = 0.25;<br />

for(i=0; i


La comman<strong>de</strong> inclu<strong>de</strong><br />

→ perm<strong>et</strong> d’insérer le fichier texte spécifié, à l’endroit où la<br />

comman<strong>de</strong> apparaît<br />

! Syntaxe :<br />

! #inclu<strong>de</strong><br />

"nom_<strong>de</strong>_fichier"<br />

ou<br />

! #inclu<strong>de</strong><br />

<br />

→ Souvent utilisé pour charger les fichiers d’en-tête (hea<strong>de</strong>rs, .h)<br />

Exemples :<br />

#inclu<strong>de</strong><br />

<br />

#inclu<strong>de</strong> <br />

→ fichiers livrés avec le compilateur<br />

→ contiennent <strong>de</strong>s définitions standard compatibles avec les bibliothèques<br />

→ ne pas les modifier !!!<br />

Recherche le fichier dans le<br />

répertoire pris par défaut pour le<br />

compilateur<br />

Recherche le fichier dans le répertoire<br />

courant, puis, s’il n’a pas été trouvé,<br />

dans le répertoire pris par défaut<br />

pour le compilateur<br />

Contenu :<br />

• déclarations <strong>de</strong> fonctions (prototypes)<br />

• définition <strong>de</strong> données externes (Exemple errno)<br />

• définition <strong>de</strong> constantes prédéfinies (Exemple : M_PI)<br />

• macro-définitions<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

109<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

110<br />

La comman<strong>de</strong> <strong>de</strong>fine<br />

Constantes prédéfinies<br />

perm<strong>et</strong> <strong>de</strong> définir :<br />

<strong>de</strong>s constantes<br />

ou<br />

<strong>de</strong>s macros<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

111<br />

#<strong>de</strong>fine<br />

Nom_Symbole Expression<br />

→ substitue par la suite dans le source toutes les occurrences <strong>de</strong><br />

Nom_Symbole par l’expression<br />

(remplacement intégral <strong>de</strong> texte)<br />

Exemple :<br />

#<strong>de</strong>fine<br />

M_PI 3.14159265<br />

#<strong>de</strong>fine<br />

PI2 (M_PI*2.0)<br />

Par la suite, si dans un programme on utilise l’instruction suivante<br />

:<br />

x = PI2*r ;<br />

le préprocesseur remplace la ligne par :<br />

x = (3.14159265*2.0)*r;<br />

→ utilisation efficace <strong>de</strong> constantes<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

112<br />

28


Macros<br />

Définition <strong>de</strong> macros<br />

→ s’apparentent visuellement à <strong>de</strong>s fonctions, mais<br />

fonctionnement plus efficace<br />

→ fonctionnent par substitution <strong>de</strong> texte<br />

Exemple :<br />

#<strong>de</strong>fine<br />

MEAN(a,b) (a+b)/2<br />

à l’utilisation, on écrit : z = MEAN(x,2-i);<br />

le préprocesseur remplace la ligne par : z = (x+2-i)/2<br />

;<br />

→ les arguments ont été remplacés par substitution <strong>de</strong> texte<br />

→ la macro MEAN( ) a été remplacée par substitution <strong>de</strong> texte<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

113<br />

!! ATTENTION !!<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

114<br />

Exemple<br />

#<strong>de</strong>fine<br />

PRODUIT(u,v) u*v<br />

à l’utilisation : z = PRODUIT(3+2,5) ;<br />

donnera : z = 3+2*5 ; (13 au lieu <strong>de</strong> 25 ! )<br />

→ Utiliser <strong>de</strong>s parenthèses !<br />

Exemples :<br />

#<strong>de</strong>fine<br />

PRODUIT(u,v)<br />

u * v<br />

#<strong>de</strong>fine<br />

Mini(a,b) a < b ? a : b<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

115<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

116<br />

29


Exemples :<br />

#<strong>de</strong>fine<br />

PRODUIT(u,v) (u)*(v)<br />

Exemples :<br />

#<strong>de</strong>fine<br />

PRODUIT(u,v) (u)*(v)<br />

#<strong>de</strong>fine<br />

Mini(a,b)<br />

(a)


Les comman<strong>de</strong>s if, if<strong>de</strong>f, ifn<strong>de</strong>f, endif<br />

Exemple<br />

→ Compilation conditionnelle<br />

#if expression<br />

#else<br />

Source compilé dans le<br />

cas contraire<br />

#endif<br />

Source compilé si<br />

l’expression est vraie<br />

#if<strong>de</strong>f symbole<br />

#else<br />

Source compilé si le<br />

symbole est défini<br />

Source compilé dans le<br />

cas contraire<br />

#endif<br />

#ifn<strong>de</strong>f symbole<br />

#else<br />

Source compilé si le<br />

symbole n’est pas<br />

défini<br />

Source compilé dans le<br />

cas contraire<br />

#endif<br />

#if<strong>de</strong>f<br />

__TURBOC__<br />

#inclu<strong>de</strong><br />

<br />

#if MODEL== __SMALL__<br />

int *px<br />

;<br />

#else<br />

void *px<br />

;<br />

#endif<br />

#endif<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

121<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

122<br />

Transtypage<br />

Initialisation <strong>de</strong> données<br />

! cast<br />

→ Conversion <strong>de</strong> type explicite<br />

→ Perm<strong>et</strong> d'indiquer au compilateur le type à utiliser<br />

Exemples :<br />

x = (long)a * b/c;<br />

void CopyDat(void<br />

*d, void *s, size_t sz)<br />

{<br />

size_t i;<br />

for(i=0; i


o Classe static :<br />

o Donnée e initialisée e au chargement du programme<br />

(expression constante évaluée e par le compilateur)<br />

o La valeur peut changer au cours du programme<br />

o Pas <strong>de</strong> co<strong>de</strong> générég<br />

lors <strong>de</strong> la déclarationd<br />

Exemple :<br />

static int x=4;<br />

o Constantes :<br />

o I<strong>de</strong>m static, , avec valeur non modifiable<br />

o Exemple :<br />

void fonctionX(void)<br />

{<br />

char t1[ ]="toto est le plus beau";<br />

→ t1 est un tableau dynamique <strong>de</strong> 22 caractères<br />

→ la chaîne <strong>de</strong> caractères est recopiée à chaque appel<br />

<strong>de</strong> la fonction fonctionX<br />

→ le contenu <strong>de</strong> t1 est modifiable<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

125<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

126<br />

! Initialisation <strong>de</strong> données<br />

o Exemple :<br />

void fonctionY(void)<br />

{<br />

static char t1[ ]="toto est le plus beau";<br />

→ t1 est un tableau statique <strong>de</strong> 22 caractères<br />

→ la chaîne <strong>de</strong> caractères est chargée au démarrage<br />

du programme<br />

→ le contenu <strong>de</strong> t1 est modifiable<br />

}<br />

! Initialisation <strong>de</strong> données<br />

o Exemple :<br />

void fonctionZ(void)<br />

{<br />

const char t1[ ]="toto est le plus beau";<br />

→ t1 est un tableau constant <strong>de</strong> 22 caractères<br />

→ la chaîne <strong>de</strong> caractères est chargée au démarrage<br />

du programme<br />

→ le contenu <strong>de</strong> t1 n'est pas modifiable<br />

}<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

127<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

128<br />

32


! Initialisation <strong>de</strong> données<br />

o Exemple :<br />

void fonctionW(void)<br />

{<br />

char *t1="toto est le plus beau";<br />

→ t1 est un pointeur initialisé sur une chaîne <strong>de</strong><br />

caractères constante (à chaque appel <strong>de</strong> fonctionW)<br />

}<br />

! Initialisation <strong>de</strong> données<br />

o Exemple :<br />

void fonctionY(void)<br />

{<br />

static char *t1="toto est le plus beau";<br />

→ t1 est un pointeur initialisé au chargement du<br />

programme sur une chaîne <strong>de</strong> caractères constante<br />

chaîne)<br />

}<br />

→ t1 pourra être modifié (pour pointer sur une autre<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

129<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

130<br />

Fonction main<br />

! Initialisation <strong>de</strong> données<br />

o Exemple :<br />

double tab[ ]={1.0, 3.0, 5.0, 7.0};<br />

char *mots[ ]={"toto","titi","tata",0};<br />

struct {<br />

char *nom;<br />

double val;<br />

} liste[100] = {<br />

{ "pi", 3.14 },<br />

{ "x", 200.12 },<br />

};<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

131<br />

! Démarrage du programme<br />

! Renvoie une valeur entière au système d'exploitation<br />

→ co<strong>de</strong> d'erreur<br />

! Adm<strong>et</strong> 3 paramètres :<br />

int main(int<br />

int argc, , char *argv*<br />

argv[ [ ], char *arge*<br />

arge[ [ ])<br />

! Paramètres "transmis" par le système d'exploitation<br />

! argc : nombre <strong>de</strong> paramètres sur la ligne <strong>de</strong> comman<strong>de</strong> (à l'invocation<br />

du programme)<br />

! argv : chaînes <strong>de</strong> caractères contenant les paramètres<br />

! arge : variables d'environnement<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

132<br />

33


Exemple<br />

pgm.exe –x3<br />

toto.dat titi.out<br />

• argc = 4<br />

• argv[0]="<br />

[0]="pgm.exe"" (avec le chemin d'accès compl<strong>et</strong>)<br />

• argv[1]="<br />

[1]="-x3"<br />

• argv[2]="<br />

[2]="toto.dat"<br />

• argv[3]="<br />

[3]="titi.out"<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

133<br />

Pointeurs <strong>de</strong> fonctions<br />

Nom <strong>de</strong> fonction → adresse <strong>de</strong> la fonction<br />

→ Pointeur <strong>de</strong> fonction<br />

Peut être utilisé pour in<strong>de</strong>xer une fonction parmi plusieurs.<br />

Exemple :<br />

void TriBulle(int<br />

int t[ ], int nb);<br />

void TriInsertion(int<br />

int t[ ], int nb);<br />

void (*fctTri<br />

fctTri)( )(int<br />

t[ ], int nb);<br />

…<br />

int tab[ ] = {1, 4, 0, -1, 2};<br />

fctTri = TriBulle;<br />

fctTri(tab,<br />

(tab,sizeof(tab)/sizeof(*tab));<br />

fctTri = TriInsertion;<br />

fctTri(tab,<br />

(tab,sizeof(tab)/sizeof(*tab));<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

134<br />

Allocation dynamique <strong>de</strong> mémoire<br />

→ Quand un espace mémoire m moire est requis, <strong>de</strong> taille<br />

inconnue lors <strong>de</strong> la conception du programme<br />

→ Pour optimiser l'utilisation <strong>de</strong> la mémoirem<br />

moire<br />

→ Deman<strong>de</strong> <strong>de</strong> mémoire m moire à l'environnement<br />

Fonctions :<br />

• void * malloc(size_t<br />

sz);<br />

Renvoie un pointeur sur la zone allouée<br />

ou NULL si pas d'espace disponible<br />

• void free(void<br />

* ptr);<br />

Libère l'espace mémoire m moire attribué par malloc<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

135<br />

Exemple<br />

int nb, , *tab;<br />

printf("Nombre <strong>de</strong> valeurs à acquérir :");<br />

scanf("%d",&<br />

("%d",&nb);<br />

tab = malloc(nb<br />

nb*sizeof(*tab));<br />

if(tab!=NULL) {<br />

int i;<br />

for(i=0; i


Fonctions à liste <strong>de</strong> paramètres<br />

variable<br />

! En C, on peut définir <strong>de</strong>s fonctions avec un<br />

nombre <strong>de</strong> paramètres inconnu :<br />

Exemples :<br />

void FctErr(int<br />

err, , …);<br />

int printf(const<br />

char *format, …);<br />

! Nécessité d'avoir au moins un paramètre connu<br />

! Gestion par va_list, va_start, va_arg, va_end<br />

→ définis dans stdarg.h<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

137<br />

Exemple<br />

void ErrPrintf(int ext, const char *fmt, …)<br />

{<br />

va_list ap;<br />

printf(ext ? "Erreur : " : "Avertissement : ");<br />

va_start(ap,fmt);<br />

vprintf(fmt,ap);<br />

va_end(ap);<br />

if(ext) exit(ext);<br />

}<br />

…<br />

F = fopen(nf="toto.dat","r");<br />

if(F==NULL) ErrPrintf(1,"Le fichier '%s' ne peut être<br />

ouvert.\n",nf);<br />

…<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

138<br />

Signal<br />

! Gestion d'événements exceptionnels<br />

! Défini dans signal.h<br />

void (*signal(int<br />

int sig, void (*handler<br />

handler)( )(int)))(int);<br />

Détermine la façon dont les signaux ultérieurs seront traités.<br />

handler : fonction <strong>de</strong> traitement du signal<br />

Fonctions prédéfinies :<br />

SIG_DFL : comportement par défaut<br />

SIG_IGN : le signal sera ignoré<br />

R<strong>et</strong>our : handler ou SIG_ERR en cas d'erreur<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

139<br />

Signaux :<br />

<strong>Langage</strong> C<br />

SIGABRT : arrêt anormal<br />

SIGFPE<br />

: erreur arithmétique<br />

SIGILL<br />

SIGINT<br />

: instruction illégale<br />

: appel au système invali<strong>de</strong><br />

SIGSEGV : accès mémoire interdit<br />

SIGTERM : <strong>de</strong>man<strong>de</strong> d'arrêt du programme<br />

Quand signal survient :<br />

1. Le comportement par défaut est rétabli<br />

2. La fonction handler est appelée<br />

3. Si la fonction rend la main, le programme se poursuit à<br />

l'endroit où il avait été interrompu<br />

M. <strong>Deloizy</strong> <strong>Langage</strong> C<br />

140<br />

35


TD1 : TYPES DE DONNÉES – CODAGE<br />

I. Caractères.<br />

I.1. Indiquer les co<strong>de</strong>s ASCII <strong>de</strong>s caractères suivants :<br />

'A', 'B', 'q', '?','*', '0' (zéro), '8', '\r', '\n', '\t'<br />

I.2. La mémoire contient les données suivantes (hexadécimal) :<br />

adresses<br />

données<br />

2A3C 43 27 65 73 74 20 65 6E<br />

2A44 20 41 53 43 49 49 2E 00<br />

Indiquer pour chaque oct<strong>et</strong> le caractère correspondant.<br />

II. Entiers.<br />

On suppose ici que les poids faibles sont situés en adresse basse.<br />

II.1. Écrire en hexadécimal puis en binaire le contenu <strong>de</strong> la mémoire pour les valeurs suivantes (entiers sur 16 bits)<br />

: 1234, 37840, 65535, -128, -1<br />

II.2. Donner les résultats <strong>de</strong>s opérations suivantes :<br />

• pour <strong>de</strong>s entiers signés codés sur 16 bits<br />

• pour <strong>de</strong>s entiers non signés codés sur 16 bits<br />

• pour <strong>de</strong>s entiers signés codés sur 32 bits<br />

1000 - 1024<br />

25000 + 30535<br />

65536 - 1<br />

II.3. Calculer les résultats <strong>de</strong>s opérations suivantes (opérateurs du C) :<br />

M<strong>et</strong>tre le résultat en binaire, hexadécimal <strong>et</strong> décimal sur 8 bits.<br />

25 & 51<br />

25 | 51<br />

25 ^ 51<br />

~25<br />

-25<br />

III. Chaînes <strong>de</strong> caractères.<br />

Indiquer le contenu mémoire obtenu avec les chaînes <strong>de</strong> caractères suivantes, selon <strong>de</strong>ux codages possibles<br />

(nombre <strong>de</strong> caractères en tête ou zéro terminal) :<br />

"TOTO"<br />

"Il fait chaud\n"<br />

"02 + 20 = 22\n"<br />

IV. Virgule flottante.<br />

Étudier les résultats obtenus avec les nombres en virgule flottante codés sur 64 bits, selon la norme IEEE 754 :<br />

e<br />

x = ± m⋅2<br />

S E' F<br />

b 63 b 62 b 52 b 51 b 0<br />

• e : exposant<br />

• m : mantisse. 1.0 ≤ m < 2.0<br />

• S : signe. 1 bit. 0 : positif, 1 : négatif<br />

• E' = e+1023. 11 bits. 1 ≤ E' ≤ 2047<br />

• F = m-1. Partie fractionnaire <strong>de</strong> la mantisse. 52 bits.<br />

Représenter le contenu mémoire correspondant aux valeurs 1.0, 2.0 <strong>et</strong> 5.0.<br />

Quelle est la valeur positive la plus p<strong>et</strong>ite possible ?<br />

Quelle est la valeur positive la plus gran<strong>de</strong> possible ?<br />

Quel est le nombre <strong>de</strong> chiffres significatifs ?<br />

V. Tableaux<br />

Soit un tableau d'entiers codés sur 16 bits <strong>et</strong> contenant les valeurs : { 2, 4, 8, 16, 32 }<br />

Représenter le contenu <strong>de</strong> la mémoire correspondant à ce tableau.<br />

Quel est le nombre d'oct<strong>et</strong>s nécessaire au stockage du tableau ?


TD2 : PREMIERS PROGRAMMES<br />

I. Écrire un programme affichant « BONJOUR » à l’écran.<br />

II. Écrire un programme qui <strong>de</strong>man<strong>de</strong> le prénom <strong>de</strong> l’utilisateur ainsi que son année <strong>de</strong> naissance. Ensuite, le<br />

programme affichera un texte sous la forme suivante :<br />

Bonjour "xxxxx" (prénom).<br />

Ton année <strong>de</strong> naissance est dddd. (année <strong>de</strong> naissance)<br />

III.a. Écrire un programme qui affiche la table <strong>de</strong> multiplication par 5 sous la forme :<br />

5 x 1 = 5<br />

5 x 2 = 10<br />

5 x 3 = 15<br />

....<br />

5 x 9 = 45<br />

III.b. Modifier le programme précé<strong>de</strong>nt en créant une fonction mult à laquelle on transm<strong>et</strong> le numéro <strong>de</strong> la table à<br />

afficher :<br />

void mult(int table)<br />

Utiliser c<strong>et</strong>te fonction dans un programme qui <strong>de</strong>man<strong>de</strong> à l’utilisateur le numéro <strong>de</strong> la table qu’il souhaite<br />

visualiser. Le programme continuera tant que l’utilisateur entre une valeur strictement positive.<br />

TD3 : UTILISATION DE TABLEAUX.<br />

I. Écrire une fonction qui <strong>de</strong>man<strong>de</strong> à l’utilisateur <strong>de</strong> faire l’acquisition <strong>de</strong> n entiers sous la forme suivante :<br />

Nombre <strong>de</strong> valeurs :<br />

Valeur n° 1 :<br />

Valeur n° 2 :<br />

Valeur n° 3 :<br />

....<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

unsigned AcqTab(int tb[], unsigned NbMax);<br />

La fonction r<strong>et</strong>ourne le nombre <strong>de</strong> valeurs saisies<br />

tb est le tableau qui doit être chargé<br />

NbMax est le nombre maximal <strong>de</strong> valeurs que peut contenir tb<br />

II. Écrire une fonction qui compte le nombre <strong>de</strong> valeurs paires dans un tableau. Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

int nbpairs(int tab[], unsigned nbval);<br />

nbval indique le nombre d'éléments contenus dans le tableau. Pourquoi ce paramètre est-il indispensable ?<br />

III. Écrire une fonction qui remplit un tableau avec <strong>de</strong>s nombres ni pairs, ni multiples <strong>de</strong> 3, en commençant par 5.<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

void inittab(int tab[], unsigned nbval);<br />

IV. Écrire une fonction trouvant le minimum <strong>et</strong> le maximum dans un tableau. Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

void minmax(double *tab, unsigned nbval, double *min, double *max);<br />

V. Soient les valeurs suivantes stockées dans un tableau : { 2, -3, 1, 0, 5, 2 }<br />

V.1 Effectuer une rotation à gauche du tableau afin d'obtenir : { -3, 1, 0, 5, 2, 2 }. Afficher le résultat.<br />

V.2. Effectuer une rotation à droite du tableau initial afin d'obtenir : { 2,2,-3, 1, 0, 5 }


TD4 : CONVERSIONS ASCII / NUMÉRIQUES<br />

I. Écrire une fonction r<strong>et</strong>ournant un entier correspondant à la valeur numérique contenue dans une chaîne transmise<br />

en paramètre. Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

int AscToInt(const char *<strong>de</strong>cstr);<br />

C<strong>et</strong>te fonction pourra être utilisée par exemple <strong>de</strong> la manière suivante :<br />

...<br />

x = AscToInt("26789");<br />

...<br />

Dans ce cas, x prendra la valeur numérique 26789.<br />

a ⋅10<br />

+ b ⋅10<br />

+<br />

On rappelle qu'un nombre abc peut s'écrire : (( ) ) c<br />

II. Écrire une fonction équivalente à la précé<strong>de</strong>nte perm<strong>et</strong>tant <strong>de</strong> convertir un nombre écrit en binaire, dont le<br />

prototype sera :<br />

int AscBinToInt(const char *binstr);<br />

III. Faire <strong>de</strong> même pour un nombre écrit en hexadécimal.<br />

int AscHexToInt(const char *hexstr);<br />

IV. Que se passe-t-il si un caractère non prévu est contenu dans la chaîne ? Proposer un moyen <strong>de</strong> remédier à ce<br />

problème.<br />

TD5 : TRAITEMENTS SUR LES CHAÎNES<br />

I. Écrire une fonction comptant le nombre <strong>de</strong> caractères contenus dans une chaîne. Le prototype <strong>de</strong> c<strong>et</strong>te fonction<br />

sera :<br />

int strlen(const char *str);<br />

II.a. Écrire une fonction comptant le nombre <strong>de</strong> caractères i<strong>de</strong>ntiques x contenus dans une chaîne. Le prototype <strong>de</strong><br />

c<strong>et</strong>te fonction sera :<br />

int nbcar(char x, const char *str); /* recherche x dans str */<br />

II.b. Modifier la fonction précé<strong>de</strong>nte pour qu'elle ne différencie pas les minuscules <strong>et</strong> majuscules.<br />

III. Écrire une fonction perm<strong>et</strong>tant <strong>de</strong> comparer <strong>de</strong>ux chaînes <strong>de</strong> caractères. Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

int cmpstr(const char *str1, const char *str2);<br />

L'entier r<strong>et</strong>ourné sera positif si str2 est situé après str1 dans un classement alphabétique <strong>et</strong> 0 si les chaînes sont<br />

i<strong>de</strong>ntiques.<br />

IV. Écrire une fonction comptant le nombre <strong>de</strong> mots dans une phrase. Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

int nbmots(const char *str);<br />

Par exemple, si str contient " le p<strong>et</strong>it train passe dans l'alpage…\n " la fonction doit r<strong>et</strong>ourner la valeur 7.


TD6 : FICHIERS<br />

I. Écrire un programme affichant à l'écran les fichiers textes dont les noms seront transmis sur la ligne <strong>de</strong><br />

comman<strong>de</strong> lors <strong>de</strong> l'appel du programme.<br />

II. Écrire un programme affichant le contenu d'un fichier quelconque en hexadécimal <strong>et</strong> en ASCII, sous la forme<br />

suivante :<br />

0000 4D 5A 78 00 BC 00 00 00 A0 04 01 00 FF FF 00 00 MZx.............<br />

0010 00 00 00 00 00 01 00 00 1E 00 00 00 01 00 00 00 ................<br />

0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br />

0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................<br />

0040 F6 38 F6 38 46 52 41 01 00 52 03 4E 53 43 4F 00 .8.8FRA..R.NSCO.<br />

0050 03 06 00 16 00 1A 00 01 04 FF FF 48 03 02 00 56 ...........H...V<br />

0060 03 03 00 66 03 08 00 7D 03 02 01 FF FF 8C 03 03 ...f............<br />

0070 CC EA 03 9A 03 EB 03 D2 03 EC 03 FC 03 ED 03 14 ................<br />

0080 04 EE 03 33 04 EF 03 69 04 F0 03 8A 04 F1 03 AE ...3...i........<br />

0090 04 F2 03 C9 04 F3 03 00 05 F4 03 23 05 F5 03 57 ...........#...W<br />

00A0 05 F6 03 7A 05 F7 03 84 05 F8 03 B1 05 F9 03 DE ...z............<br />

00B0 05 FA 03 02 06 FB 03 17 06 FC 03 26 06 FD 03 35 ...........&...5<br />

III. Statistiques sur un fichier<br />

III.1. Écrire un programme qui compte les mots contenus dans un fichier texte.<br />

III.2. (optionnel) Modifier le programme pour indiquer (dans l'ordre <strong>de</strong> la fréquence d'apparition) les mots présents<br />

dans le fichier.


TP1 : DÉCLARATIONS, PREMIERS PROGRAMMES, DÉBOGUAGE<br />

I. Écrire un programme affichant "Bonjour".<br />

II. Soit le programme suivant :<br />

#inclu<strong>de</strong> <br />

/* Affichage <strong>de</strong> la table <strong>de</strong> multiplication par m */<br />

void mtable(int m, int nmax)<br />

{<br />

int i;<br />

for(i=1; i


TP2 : MANIPULATIONS DE CHAÎNES DE CARACTÈRES<br />

I. Saisie <strong>de</strong> chaînes<br />

Définir un tableau <strong>de</strong> 256 caractères.<br />

Faire la saisie d'une chaîne <strong>de</strong> caractères (limitée à 20 caractères) en utilisant :<br />

la fonction scanf<br />

la fonction g<strong>et</strong>s<br />

la fonction fg<strong>et</strong>s<br />

Dans chaque cas,<br />

Afficher normalement la chaîne saisie (en utilisant printf)<br />

Afficher en hexadécimal le co<strong>de</strong> ASCII <strong>de</strong>s 80 premiers oct<strong>et</strong>s du tableau. (On pourra concevoir une fonction qui<br />

affiche en hexadécimal le contenu d'un tableau <strong>de</strong> caractères)<br />

Y a-t-il <strong>de</strong>s caractères indésirables dans la chaîne saisie ?<br />

Que se passe-t-il si l'utilisateur entre plus <strong>de</strong> 20 caractères ? Comment remédier à ce problème ?<br />

Écrire une fonction qui "n<strong>et</strong>toie" une chaîne saisie par fg<strong>et</strong>s (en enlevant le caractère '\n' résiduel).<br />

II. Traitements sur les chaînes<br />

II.1. Écrire une fonction qui compte le nombre <strong>de</strong> caractères contenus dans une chaîne. Comparer les résultats<br />

obtenus avec la fonction strlen.<br />

II.1.a. 2 Comparer les temps d'exécution <strong>de</strong> votre fonction par rapport à strlen. On pourra utiliser pour cela la<br />

fonction difftime (définie dans time.h) appliquée sur un très grand nombre d'appels <strong>de</strong> chacune <strong>de</strong>s fonctions.<br />

Essayer d'optimiser votre fonction afin qu'elle s'exécute en un temps minimal.<br />

II.2. Écrire une fonction qui compte le nombre <strong>de</strong> voyelles contenues dans une chaîne <strong>de</strong> caractères (sans<br />

distinction <strong>de</strong>s minuscules <strong>et</strong> majuscules).<br />

II.3. Écrire une fonction qui compte le nombre <strong>de</strong> mots contenus dans une chaîne.<br />

III. Interprétation d'une chaîne <strong>de</strong> caractères.<br />

III.1. Faire la saisie d'une chaîne donnée sous la forme : valeur numérique opérateur valeur numérique<br />

Par exemple : "2.4 + -3.5"<br />

L'opérateur pourra être un caractère parmi +, -, *, / <strong>et</strong> ^ (élévation à la puissance)<br />

Faire une fonction qui r<strong>et</strong>ourne la valeur numérique correspondant à l'expression écrite dans la chaîne. On pourra<br />

utiliser la fonction strtod pour l'évaluation <strong>de</strong>s données numériques.<br />

III.2. 2 Améliorer c<strong>et</strong>te fonction pour qu'elle prenne en charge les parenthèses, perm<strong>et</strong>tant ainsi d'écrire par<br />

exemple : 2.4 + (-3.5)<br />

Pourrait-on envisager d'évaluer une expression du type : 2.4 + (0.5-4.0)<br />

2 Exercices optionnels


TP3 : TABLEAUX DE DONNÉES<br />

I. Acquisition <strong>de</strong> données<br />

I.1. Déclarer un tableau <strong>de</strong> 40 entiers<br />

Écrire une fonction perm<strong>et</strong>tant <strong>de</strong> saisir au clavier les nb premiers éléments du tableau (0 ≤ nb < 40).<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

void AcqTab(int *tab, unsigned nb);<br />

I.2. Écrire une fonction affichant à l'écran les n premiers nombres d'un tableau, en passant une ligne toutes les nbl<br />

valeurs.<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

void AffTab(int *tab, unsigned n, unsigned nbl);<br />

II. Nombres aléatoires<br />

II.1. Écrire une fonction qui remplit un tableau avec n valeurs aléatoires. On utilisera la fonction rand(), définie<br />

dans stdlib.h. Afficher les résultats obtenus.<br />

Exécuter plusieurs fois le programme. Conclure.<br />

II.2. 3 Initialiser le générateur <strong>de</strong> nombres aléatoires en utilisant la fonction srand() (voir prototype). L'initialisation<br />

sera réalisée à l'ai<strong>de</strong> <strong>de</strong> la fonction time() (définie dans time.h).<br />

Observer <strong>de</strong> nouveau les résultats obtenus.<br />

II.3. Écrire une nouvelle fonction qui effectue un tirage <strong>de</strong> 6 valeurs aléatoires distinctes, <strong>et</strong> comprises entre 1 <strong>et</strong> 49.<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

unsigned *Loto(void);<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne un pointeur sur le tableau contenant les 6 valeurs du tirage.<br />

III. Tris<br />

III.1. Constituer un tableau <strong>de</strong> N valeurs aléatoires. Classer en ordre croissant ce tableau en utilisant les algorithmes<br />

suivants :<br />

tri à bulle<br />

tri par sélection<br />

tri <strong>de</strong> Hoare<br />

III.2. 3 Mesurer les durées d'exécution <strong>de</strong>s différents algorithmes appliqués sur les mêmes tableaux, en utilisant la<br />

fonction clock() pour différentes valeurs <strong>de</strong> N.<br />

Comparer les résultats obtenus avec la fonction qsort() définie dans stdlib.h.<br />

III.3. Définir un tableau <strong>de</strong> chaînes <strong>de</strong> caractères.<br />

Classer en ordre croissant, puis en ordre décroissant ce tableau en utilisant la fonction qsort.<br />

3 Exercices optionnels.


TP4 : FICHIERS<br />

I. Lecture d'un fichier texte<br />

Éditer (avec un éditeur <strong>de</strong> textes) un texte quelconque <strong>de</strong> quelques lignes.<br />

Enregistrer ce fichier sur le disque.<br />

Créer un programme qui lit ce fichier <strong>et</strong> affiche son contenu. Le programme affichera finalement le nombre <strong>de</strong><br />

lignes composant le fichier.<br />

II. Cryptage d'un fichier<br />

On se propose <strong>de</strong> crypter <strong>de</strong> manière simple le fichier précé<strong>de</strong>mment créer (afin d'en interdire la lecture avec un<br />

simple éditeur <strong>de</strong> textes).<br />

II.1. Faire la fonction <strong>de</strong> cryptage<br />

L'oct<strong>et</strong> transmis sera divisé en <strong>de</strong>ux quart<strong>et</strong>s. Les bits <strong>de</strong>s quart<strong>et</strong>s seront ensuite mélangés comme indiqué ci<strong>de</strong>ssous.<br />

La fonction r<strong>et</strong>ournera le complément du résultat obtenu.<br />

Exemple : Soit le caractère 'A' <strong>de</strong> co<strong>de</strong> ASCII 0x41<br />

On coupe ce co<strong>de</strong> ASCII en <strong>de</strong>ux quart<strong>et</strong>s ; on obtient 4 <strong>et</strong> 1, soit en binaire : 0100 <strong>et</strong> 0001.<br />

On mélange les quart<strong>et</strong>s en alternant les bits :<br />

0 1 0 0<br />

0 0 0 1<br />

0<br />

1 0 0 1 0 0 0<br />

On obtient alors un oct<strong>et</strong> contenant 0x48, soit, en binaire : 01001000<br />

Ensuite on prend le complément <strong>de</strong> c<strong>et</strong>te valeur <strong>et</strong> on obtient 10110111, soit en hexadécimal 0xB7.<br />

Si le caractère 'A' est transmis à la fonction, celle-ci r<strong>et</strong>ournera donc la valeur B7 H (soit 183 en décimal).<br />

II.2. Écrire une fonction réalisant la lecture du fichier Fin, qui crypte ce fichier <strong>et</strong> écrit le résultat dans Fout.<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

int CryptFile(FILE *Fin, FILE *Fout);<br />

C<strong>et</strong>te fonction r<strong>et</strong>ournera 1 si le cryptage s'est bien passé, <strong>et</strong> 0 en cas d'erreur.<br />

Remarque : Le fichier Fout <strong>de</strong>vra avoir été ouvert en binaire pour assurer une écriture correcte dans le fichier.<br />

II.3. Faire le programme compl<strong>et</strong>.<br />

L'utilisateur <strong>de</strong>vra entrer le nom du fichier à crypter <strong>et</strong> le nom du fichier crypté.<br />

II.4. 4 On souhaite appeler le programme <strong>de</strong> cryptage selon la syntaxe suivante :<br />

NomProg NomFichier<br />

où NomProg est le nom du programme exécutable (.exe) <strong>et</strong> NomFichier est le nom du fichier à crypter.<br />

Le fichier transmis sera alors crypté, le résultat étant mis à la place du fichier d'origine.<br />

Faire la lecture <strong>de</strong>s arguments <strong>de</strong> la fonction main(), en sachant que le prototype <strong>de</strong> main() est<br />

int main(int argc, char *argv[]);<br />

où argc représente le nombre d'arguments sur la ligne <strong>de</strong> comman<strong>de</strong> (y compris le nom du programme) <strong>et</strong> argv est<br />

un tableau <strong>de</strong> chaînes <strong>de</strong> caractères contenant les différents arguments.<br />

Écrire le programme compl<strong>et</strong>. On pourra utiliser les fonctions tmpnam() , rename() <strong>et</strong> remove() en s'assurant que le<br />

fichier d'origine ne doit être détruit que si le fichier crypté a été construit sans erreur.<br />

Proposer un système perm<strong>et</strong>tant <strong>de</strong> crypter ou décrypter <strong>de</strong> manière automatique le fichier transmis en argument.<br />

4 Exercice optionnel.


TP5 : STRUCTURES<br />

I. Définition d'une structure<br />

Définir un type <strong>de</strong> structure TInfo pouvant contenir <strong>de</strong>s informations sur <strong>de</strong>s personnes :<br />

le nom (chaîne <strong>de</strong> caractères - maximum 40 caractères)<br />

le prénom (chaîne <strong>de</strong> caractères - maximum 40 caractères)<br />

le jour <strong>de</strong> naissance (entier court - char)<br />

le mois <strong>de</strong> naissance (entier court - char)<br />

l'année <strong>de</strong> naissance (entier court - short)<br />

le numéro <strong>de</strong> téléphone (tableau <strong>de</strong> 15 entiers courts – type char)<br />

le nombre <strong>de</strong> chiffres composant le numéro <strong>de</strong> téléphone (entier court - char)<br />

l'adresse Email (chaîne <strong>de</strong> caractères - maximum 60 caractères)<br />

II. Encombrement mémoire<br />

Observer (avec l'opérateur sizeof) l'encombrement mémoire <strong>de</strong> c<strong>et</strong>te structure.<br />

III. Tableau <strong>de</strong> structures<br />

Définir un tableau perm<strong>et</strong>tant <strong>de</strong> mémoriser 1000 structures TInfo, en initialisant les <strong>de</strong>ux premières structures avec<br />

vos coordonnées.<br />

Indiquer l'encombrement mémoire <strong>de</strong> ce tableau.<br />

IV. Acquisition <strong>de</strong>s champs<br />

Ecrire une fonction perm<strong>et</strong>tant d'acquérir au clavier une structure TInfo.<br />

C<strong>et</strong>te fonction posera les questions suivantes :<br />

Entrer le nom :<br />

Entrer le prénom :<br />

Entrer la date <strong>de</strong> naissance sous la forme jj/mm/aaaa :<br />

Entrer le numéro <strong>de</strong> téléphone (max 15 chiffres) :<br />

Entrer l'Email :<br />

Le prototype <strong>de</strong> c<strong>et</strong>te fonction sera :<br />

void AcqInfo(struct TInfo *info);<br />

V. Acquisition <strong>et</strong> enregistrement dans un fichier<br />

Faire un programme perm<strong>et</strong>tant d'acquérir au clavier <strong>de</strong>s informations sur <strong>de</strong>s personnes <strong>et</strong> <strong>de</strong> les enregistrer dans<br />

un fichier disque. On pourra utiliser pour ceci la fonction fwrite(), définie dans stdio.h.<br />

Le fichier créé peut-il être visualisé à l'ai<strong>de</strong> d'un simple éditeur <strong>de</strong> textes ?<br />

VI. Relecture du fichier<br />

Modifier le programme précé<strong>de</strong>nt pour initialiser le tableau <strong>de</strong> structures à partir du fichier enregistré sur le disque,<br />

s'il existe.<br />

VII. 5 Classement <strong>de</strong>s informations.<br />

Réaliser le tri du tableau <strong>de</strong> structures selon différents critères (par exemple, le nom, le prénom ou l'âge).<br />

5 Exercice optionnel


TP6 : ÉTUDE DE FONCTIONS MATHÉMATIQUES<br />

I. Définition <strong>de</strong> fonctions mathématiques<br />

Écrire les fonctions (informatiques) perm<strong>et</strong>tant <strong>de</strong> calculer les fonctions mathématiques suivantes :<br />

f ( x)<br />

=<br />

1<br />

10<br />

∑<br />

sin<br />

((2<br />

⋅i<br />

+ 1) ⋅ x)<br />

i= 0 2 ⋅i<br />

+<br />

1<br />

sin( x)<br />

f<br />

2<br />

( x)<br />

= f<br />

3(<br />

x)<br />

= sin(10 ⋅ x)<br />

⋅ exp( −x)<br />

x<br />

Constituer un tableau <strong>de</strong> pointeurs <strong>de</strong> fonctions, perm<strong>et</strong>tant d'accé<strong>de</strong>r par la suite aux fonctions préalablement<br />

définies.<br />

II. Calcul <strong>de</strong>s fonctions<br />

Écrire un programme qui <strong>de</strong>man<strong>de</strong> à l'utilisateur :<br />

le numéro <strong>de</strong> la fonction qu'il souhaite étudier (1, 2 ou 3)<br />

la valeur minimale <strong>de</strong> l'abscisse (Xmin)<br />

la valeur maximale <strong>de</strong> l'abscisse (Xmax)<br />

le nombre <strong>de</strong> points à utiliser pour l'étu<strong>de</strong> (nbp)<br />

Le programme <strong>de</strong>vra créer <strong>de</strong> manière dynamique un tableau perm<strong>et</strong>tant <strong>de</strong> ranger les nbp points calculés (les<br />

ordonnées) <strong>de</strong> la fonction (utiliser malloc(), définie dans stdlib.h)<br />

On cherchera ensuite dans ce tableau les valeurs minimale <strong>et</strong> maximale <strong>de</strong> la fonction. Ces informations seront<br />

affichées à l'écran.<br />

Remarque : On n'oubliera pas <strong>de</strong> libérer l'espace mémoire alloué dynamiquement dès que les données ne sont plus<br />

nécessaires (utilisation <strong>de</strong> free()).<br />

III. Traitement <strong>de</strong>s exceptions.<br />

Dans certains cas, la fonction mathématique peut déclencher une erreur (par exemple une division par 0). Prévoir la<br />

résolution du problème en utilisant la fonction signal(), définie dans signal.h. C<strong>et</strong>te fonction perm<strong>et</strong> l'appel d'une<br />

fonction <strong>de</strong> gestion d'erreur dès qu'un "signal" est capté. Dans notre cas, on utilisera le signal SIGFPE (Floating<br />

Point Exception).<br />

IV. Ecriture <strong>de</strong>s résultats dans un fichier<br />

Écrire une fonction perm<strong>et</strong>tant <strong>de</strong> ranger les couples (abscisses, ordonnées) dans un fichier texte. Chaque ligne du<br />

fichier qui contiendra les valeurs <strong>de</strong> l'abscisse <strong>et</strong> <strong>de</strong> l'ordonnée, séparées par un caractère ';'.<br />

Ce fichier pourra être récupéré par un autre programme, comme un tableur (type Excel) <strong>et</strong> ceci perm<strong>et</strong>tra ainsi <strong>de</strong><br />

manière simple <strong>de</strong> réaliser le tracé <strong>de</strong> la fonction 6 .<br />

V. Écriture d'une fonction <strong>de</strong> gestion d'erreur<br />

Le programme écrit peut provoquer <strong>de</strong>s erreurs. Écrire une fonction perm<strong>et</strong>tant <strong>de</strong> m<strong>et</strong>tre fin au programme<br />

(utiliser la fonction exit()), en affichant un message d'erreur explicite.<br />

C<strong>et</strong>te fonction aura le prototype suivant (<strong>et</strong> utilisera vprintf()) :<br />

void ErrPrintf(const char *format, ...);<br />

On pourra ainsi appeler c<strong>et</strong>te fonction <strong>de</strong> la manière suivante :<br />

ErrPrintf("Xmax [%G] doit être supérieur à Xmin [%G].",Xmax,Xmin);<br />

ou bien :<br />

ErrPrintf("Le fichier '%s' ne peut être ouvert",nom_fichier);<br />

<strong>et</strong>c.…<br />

6 Exercice facultatif.


TP7 : ACQUISITION ET TRAITEMENT DE DONNÉES<br />

I. Signal analogique<br />

I.1 Échantillonner un signal analogique avec les cartes d'entrées-sorties.<br />

On prendra :<br />

F E = 1KHz<br />

Nombre d'échantillons = 1024<br />

I.2. Déterminer numériquement :<br />

• Les valeurs extrêmes du signal (en volts)<br />

• La valeur <strong>et</strong> l'instant <strong>de</strong> la plus forte pente<br />

II. Filtre numérique.<br />

On m<strong>et</strong> en œuvre un filtre dont l'équation <strong>de</strong> récurrence s'écrit :<br />

ek+<br />

1<br />

− yk<br />

yk+<br />

1<br />

= yk<br />

+<br />

U<br />

N<br />

Déterminer expérimentalement la nature du filtre.<br />

La fréquence d'échantillonnage est égale à 1 kHz.<br />

Quels sont le gain <strong>et</strong> la fréquence <strong>de</strong> coupure pour N = 1 <strong>et</strong> N = 16<br />

filtre<br />

Y

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!