09.01.2015 Views

Langage C - Pages de Michel Deloizy - Free

Langage C - Pages de Michel Deloizy - Free

Langage C - Pages de Michel Deloizy - Free

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

LICENCE SPI - EEA<br />

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

Éléments <strong>de</strong> Cours<br />

M. <strong>Deloizy</strong> Édition du 5 février 2009<br />

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


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

INTRODUCTION<br />

Le langage C est un langage structuré conçu pour obtenir un haut niveau dřoptimisation en produisant une taille <strong>de</strong> co<strong>de</strong><br />

réduite et une gran<strong>de</strong> rapidité dřexécution.<br />

Son écriture peut sembler quelque peu hermétique au programmeur non initié ; elle permet cependant une écriture<br />

efficace <strong>de</strong> programmes, le langage définissant très peu <strong>de</strong> mots clés et autorisant largement les omissions<br />

(réglementées) et les contractions. Ceci constitue parfois une difficulté qui nécessite une bonne connaissance du langage<br />

et une gran<strong>de</strong> rigueur lors <strong>de</strong> la transcription <strong>de</strong> programmes.<br />

Pour permettre au compilateur dřobtenir une bonne efficacité, le niveau <strong>de</strong> protection du langage est très faible (on<br />

pourra fréquemment « planter » la machine). Par ailleurs, il permet <strong>de</strong> disposer <strong>de</strong>s ressources avancées du système<br />

comme les écrans, les claviers, les disques et autres périphériques ; Il permet également en standard dřaccé<strong>de</strong>r aux<br />

ressources proches du matériel (par exemple la mémoire) ce qui rend le langage C « universel » et explique sa fréquente<br />

utilisation dans <strong>de</strong> nombreux domaines.<br />

Une autre caractéristique très intéressante du langage C est quřil offre <strong>de</strong>s mécanismes assurant une bonne portabilité, à<br />

condition que le programmeur veuille bien se plier à lřécriture <strong>de</strong>s programmes « dans les règles <strong>de</strong> lřArt ».<br />

I. Constitution d’un programme C<br />

DESCRIPTION DU LANGAGE<br />

I.1. Généralités<br />

Un programme C est un ensemble constitué <strong>de</strong> modules, eux-mêmes composés <strong>de</strong> fonctions.<br />

Pour le programmeur, un module est en réalité un fichier texte (dřextension « .c ») que lřon saisit avec un éditeur <strong>de</strong><br />

textes ; il sřagit du fichier source codé en ASCII dans la machine.<br />

Les fonctions décrivent les actions à réaliser dans le programme. Elles peuvent appeler dřautres fonctions qui ellesmêmes<br />

peuvent en appeler dřautres, etc.<br />

En C, une fonction particulière permet le démarrage du programme : elle se nomme main(), ce qui signifie<br />

« principale ». Lorsque lřon exécute un programme C sur une machine, tout se passe comme si le système<br />

dřexploitation <strong>de</strong> lřordinateur appelait cette fonction (le système dřexploitation étant alors vu comme étant, pour la<br />

fonction main, une fonction <strong>de</strong> niveau supérieur).<br />

I.2. Syntaxe<br />

I.2.a. Commentaires.<br />

En C, les commentaires sont encadrés par les séquences <strong>de</strong> caractères /* et */. Ils ne peuvent pas être<br />

imbriqués (pas <strong>de</strong> commentaires en commentaire). Les commentaires peuvent occuper plusieurs lignes.<br />

Toute information notée en commentaire sera ignorée par le compilateur.<br />

Aujourd'hui, certains compilateurs reconnaissent la séquence // comme étant le début d'un commentaire<br />

occupant le reste <strong>de</strong> la ligne (héritage du C++). Ceci n'est malheureusement pas le cas <strong>de</strong> tous les<br />

compilateurs et <strong>de</strong>vra être évité dans un souci <strong>de</strong> portabilité.<br />

I.2.b. Noms <strong>de</strong> symboles.<br />

Les symboles sont composés d'un ensemble <strong>de</strong> lettres, <strong>de</strong> chiffres et du caractère '_'. Le premier caractère<br />

ne pouvant être un chiffre.<br />

Les caractères accentués ne sont pas acceptés.<br />

I.2.c. Minuscules et majuscules.<br />

Les minuscules et majuscules sont différenciés en C (Toto est différent <strong>de</strong> toto). En règle générale, on<br />

évitera d'utiliser <strong>de</strong>s noms <strong>de</strong> symboles se différenciant uniquement par la présence <strong>de</strong> minuscules et/ou<br />

majuscules, ceci étant source <strong>de</strong> confusion et d'erreurs.<br />

-2-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

I.3. Mots clés<br />

Le langage C utilise un nombre très restreint <strong>de</strong> mots réservés. Ces mots qui ne doivent pas être utilisés comme noms <strong>de</strong><br />

symboles sont les suivants :<br />

auto break case char const continue <strong>de</strong>fault do<br />

double else enum extern float for goto if<br />

int long register return short signed sizeof static<br />

struct switch type<strong>de</strong>f union unsigned void volatile while<br />

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

Le langage C propose un jeu <strong>de</strong> types <strong>de</strong> données assez complet tout en offrant <strong>de</strong>s outils permettant <strong>de</strong> sřaffranchir <strong>de</strong><br />

lřimplémentation.<br />

II.1. Les types <strong>de</strong> base<br />

II.1.a. char :<br />

II.1.b. int :<br />

est le type <strong>de</strong> données le plus petit. Il permet <strong>de</strong> manipuler <strong>de</strong>s caractères et est souvent composé <strong>de</strong><br />

8 bits. Il est signé par défaut. Il peut être vu comme étant un entier très court. Cřest le type <strong>de</strong> données <strong>de</strong><br />

taille élémentaire.<br />

est un entier. Cřest le type <strong>de</strong> données qui pris par défaut par le langage (quand le type <strong>de</strong> donnée nřest<br />

pas précisé). Il est en général constitué du nombre <strong>de</strong> bits correspondant au processeur sur lequel est<br />

exécuté le programme. En principe, le type int est composé dřau moins 16 bits. Il est signé par défaut.<br />

II.1.c. float :<br />

est un nombre codé en virgule flottante, permettant dřobtenir une gran<strong>de</strong> dynamique. Il est adapté aux<br />

calculs scientifiques et ne convient pas pour les énumérations (à cause <strong>de</strong> sa précision limitée).<br />

II.2. Les types dérivés<br />

II.2.a. unsigned char :<br />

est un caractère non signé, permettant <strong>de</strong> manipuler uniquement <strong>de</strong>s entiers (très courts) positifs.<br />

II.2.b. signed char :<br />

est un caractère signé. char étant signé par défaut, signed peut être utile dans certains environnements qui<br />

prennent le type char comme non signé.<br />

II.2.c. unsigned int ou unsigned :<br />

est un entier non signé.<br />

II.2.d. short :<br />

est un entier signé qui peut être plus petit que int (souvent 16 bits).<br />

II.2.e. unsigned short :<br />

est un short non signé.<br />

II.2.f. long int ou long :<br />

est un entier signé à gran<strong>de</strong> précision ; il est composé dřun nombre <strong>de</strong> bits supérieur ou égal à celui <strong>de</strong> int.<br />

II.2.g. unsigned long int ou unsigned long :<br />

est un long int non signé.<br />

II.2.h. double :<br />

correspond à un long float. Il contient un nombre à virgule flottante dont le nombre <strong>de</strong> chiffres<br />

significatifs et la dynamique sont supérieurs ou égaux à float.<br />

-3-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

II.2.i. long double :<br />

contient un nombre à virgule flottante dont le nombre <strong>de</strong> chiffres significatifs et la dynamique sont<br />

supérieurs ou égaux à double.<br />

II.2.j. Dynamique <strong>de</strong>s nombres :<br />

A titre indicatif, la dynamique <strong>de</strong>s nombres est indiquée dans les tableaux ci-<strong>de</strong>ssous :<br />

ENTIERS Valeur minimale Valeur maximale<br />

8 bits signé -128 127<br />

8 bits non signé 0 255<br />

16 bits signé -32768 32767<br />

16 bits non signé 0 65535<br />

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

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

VIRGULE FLOTTANTE Chiffres significatifs Exposant min/max<br />

4 octets 7 38<br />

8 octets 15 308<br />

10 octets 19 4932<br />

Remarques :<br />

Le langage C ne définit pas un nombre <strong>de</strong> bits (donc une précision) correspondant à chaque type <strong>de</strong> données. Celui-ci<br />

dépend donc du matériel sur lequel sera exécuté le programme, et surtout du compilateur utilisé. Il existe simplement<br />

une recommandation concernant la taille <strong>de</strong>s entiers (int) qui <strong>de</strong>vront être codés sur au moins 16 bits.<br />

La seule certitu<strong>de</strong> concerne le classement <strong>de</strong>s encombrements (notés E) :<br />

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

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

Lors dřopérations sur <strong>de</strong>s entiers, le type int sera automatiquement utilisé par le compilateur (sauf si un terme long int<br />

apparaît dans lřexpression). Cřest le cas également lors <strong>de</strong> la transmission <strong>de</strong> paramètres entiers à une fonction.<br />

Lors dřopérations sur <strong>de</strong>s nombres à virgule flottante, le type double sera utilisé par le compilateur ; Le type float sera<br />

donc réservé au rangement <strong>de</strong> données en gran<strong>de</strong> quantité.<br />

Lřopérateur sizeof permet <strong>de</strong> connaître la taille dřune donnée, exprimée en nombre <strong>de</strong> données <strong>de</strong> taille élémentaire<br />

(sizeof(char) vaut 1). En général, puisque le type char est souvent codé sur un octet, sizeof donne la taille <strong>de</strong>s données<br />

en octets.<br />

Il nřexiste pas en C <strong>de</strong> type booléen. Le type entier (int) sera utilisé lors <strong>de</strong> lřévaluation dřune expression logique. Une<br />

expression sera dite « vraie » si elle est non nulle ; Elle sera « fausse » si elle est nulle.<br />

II.3. Les types composés<br />

Les types <strong>de</strong> données énoncés précé<strong>de</strong>mment permettent <strong>de</strong> constituer <strong>de</strong>s données plus complexes :<br />

II.3.a. les tableaux :<br />

Ils sont constitués dřun ensembles <strong>de</strong> données <strong>de</strong> même type, placées <strong>de</strong> manière contiguë en mémoire.<br />

II.3.b. les structures :<br />

Elles sont constituées dřun ensemble <strong>de</strong> types <strong>de</strong> données. Elles permettent <strong>de</strong> décrire cette donnée en lui allouant un<br />

ensemble <strong>de</strong> variables la caractérisant.<br />

Par exemple, pour décrire un individu, on indiquera son nom, son âge, sa taille, son poids et son sexe (0 pour un<br />

homme, 1 pour une femme).<br />

Lřindividu constituera une donnée <strong>de</strong> type structure dont les « champs » seront :<br />

- le nom (tableau <strong>de</strong> caractères)<br />

- lřâge (un entier court non signé)<br />

- la taille (un nombre à virgule flottante)<br />

- le poids (un nombre à virgule flottante)<br />

- le sexe (un caractère)<br />

Les structures seront développées ultérieurement (page 28).<br />

-4-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

II.3.c. les unions :<br />

Il sřagit <strong>de</strong> structures particulières dans lesquelles tous les champs sont situés à la même adresse. Les unions sont utiles<br />

lors du développement <strong>de</strong> programmes à bas niveau (proches du matériel), et permettent ainsi une bonne portabilité du<br />

langage.<br />

Remarque :<br />

On peut évi<strong>de</strong>mment combiner les structures et les tableaux, permettant ainsi dřobtenir <strong>de</strong>s tableaux <strong>de</strong><br />

structures ou <strong>de</strong>s structures contenant <strong>de</strong>s tableaux.<br />

II.4. Autres types<br />

II.4.a.<br />

II.4.b.<br />

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

le programmeur peut à son aise renommer un type <strong>de</strong> donnée par lřintermédiaire du mot clé type<strong>de</strong>f.<br />

Utilisé à bon escient, cela permet souvent une meilleure lisibilité <strong>de</strong>s programmes.<br />

Exemples :<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 />

void<br />

nřest pas un type <strong>de</strong> donnée. Ce mot clé permet dřindiquer lřabsence <strong>de</strong> donnée ou la méconnaissance du<br />

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

III. La déclaration <strong>de</strong>s variables<br />

Pour déclarer une variable, il suffit dřindiquer le type choisi, suivi du nom <strong>de</strong> la variable. Plusieurs variables <strong>de</strong> même<br />

type peuvent être déclarées simultanément.<br />

La fin <strong>de</strong> la déclaration est marquée par le caractère Ř;ř<br />

Exemples :<br />

char x ; x est un caractère (sur 8 bits : [-128…+127])<br />

int i, j, k ; i, j et k sont <strong>de</strong>s entiers (sur 16 bits : [-32768…+32767])<br />

unsigned arthur ; arthur est un entier non signé (sur 16 bits : [0…+65535])<br />

unsigned char octet ; octet est un caractère non signé(sur 8 bits : [0…+255])<br />

Pour déclarer <strong>de</strong>s tableaux <strong>de</strong> données, on fait suivre le nom <strong>de</strong> variable par le nombre dřéléments que peut contenir<br />

chaque ligne du tableau ; Cette valeur obligatoirement constante doit figurer entre crochets.<br />

Exemples :<br />

char tab[10] ; tab est un tableau pouvant contenir 10 caractères<br />

double f[5][3] ; f est un tableau <strong>de</strong> 5 lignes et 3 colonnes (15 x double)<br />

Remarques :<br />

A lřutilisation, le premier élément du tableau est dřindice 0.<br />

Les éléments dřun tableau sont rangés consécutivement en mémoire (Ex. <strong>de</strong> tab[0] à tab[9])<br />

Pour les tableaux multi-dimensionnés, le <strong>de</strong>rnier indice « court » le plus vite ; Par exemple, pour le tableau f, le<br />

rangement en mémoire sera :<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 />

IV. Constantes<br />

Lors <strong>de</strong> lřécriture <strong>de</strong> données constantes, la syntaxe permet dřindiquer au compilateur le type <strong>de</strong> la constante :<br />

Ecritures<br />

Exemples<br />

Caractère Řxř ŘAř, Ř=ř, Ř\\ř, Ř\řř<br />

Entier nnn ou nnn 421, 0, -12, +456<br />

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

Entier hexadécimal 0xnn ou 0xNN 0x4A, 0x00ff<br />

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

Chaîne <strong>de</strong> caractères "xxxxxx" "Bonjour les amis"<br />

-5-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

Remarque : le caractère \ est le caractère dŘéchappement en C. Il permet dřintroduire une séquence à signification<br />

particulière.<br />

Séquences dřéchappement possibles :<br />

Séquence Signification Exemple Résultat<br />

\r Retour chariot (en début <strong>de</strong> ligne). 0x0D printf("\rbonjour") bonjour<br />

\n Saut à la ligne suivante. 0x0A printf("bonjour\n") bonjour<br />

\t Tabulation. 0x09 printf("Rés.\tMoy.\n") Rés. Moy. <br />

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

\ř Caractère ' x='\''-0x20 x=39-32x=7<br />

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

\xnn ou \Xnn Nombre hexadécimal (n : digit hexa) 0x3B, 0xFA8 59, 4008<br />

\ooo Nombre octal (o : digit octal) \012, \033 10, 27<br />

On peut également préciser le type <strong>de</strong> constantes grâce à lřadjonction <strong>de</strong> suffixes :<br />

Suffixe : sans U ou u L ou l F ou f<br />

Entier int unsigned int long float<br />

Virgule flottante double - long double Float<br />

Exemples :<br />

12L : 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 : constante unsigned long int<br />

-6-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

V. Organisation générale d'un module<br />

Un programme C est constitué <strong>de</strong> un ou plusieurs modules (fichiers sources d'extension ".c").<br />

Chaque module sera organisé <strong>de</strong> la manière suivante :<br />

déclarations<br />

…<br />

fonction1<br />

…<br />

fonction2<br />

…<br />

…<br />

La zone <strong>de</strong> déclaration initiale permet <strong>de</strong> définir <strong>de</strong>s données globales au module ; Elles seront reconnues par l'ensemble<br />

<strong>de</strong>s fonctions définies dans le module.<br />

Pour l'ensemble <strong>de</strong>s modules, on ne <strong>de</strong>vra définir qu'une fonction main() qui sera le point <strong>de</strong> démarrage du programme.<br />

VI. Constitution d'une fonction<br />

VI.1. Définition d'une fonction<br />

Pour définir une fonction, on déclare le nom <strong>de</strong> la fonction, avec le type <strong>de</strong> valeur retournée par la fonction, ainsi que<br />

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

Ensuite on définit le corps <strong>de</strong> la fonction (entre accola<strong>de</strong>s). Celui-ci a la structure suivante :<br />

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

blocs d'instructions<br />

retour à la fonction appelante (avec un éventuel renvoi d'une valeur)<br />

Exemple :<br />

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

{<br />

double res;<br />

res = a + b;<br />

return res;<br />

}<br />

On rencontre encore quelques fois l'ancienne syntaxe (avant la standardisation du C Ansi) qu'il vaut mieux éviter, sauf<br />

si le compilateur ne reconnaît que celle-ci :<br />

double somme(a, b)<br />

double a, b;<br />

{<br />

double res;<br />

res = a + b;<br />

return res;<br />

}<br />

Remarques :<br />

lors <strong>de</strong> la définition d'une fonction, le caractère ";" doit être omis en fin <strong>de</strong> ligne<br />

en C, les paramètres sont toujours transmis par valeur<br />

si une fonction ne doit rien retourner (il s'agit alors d'une procédure), on la définit void :<br />

-7-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

Exemple :<br />

void init_glob()<br />

{<br />

A=0;<br />

TOT=12E4;<br />

}<br />

si le type retourné par la fonction est omis, le compilateur supposera qu'elle retourne une valeur <strong>de</strong> type int.<br />

lorsqu'une fonction n'a pas été déclarée antérieurement, le compilateur supposera qu'elle retourne un type int<br />

(d'où la nécessité <strong>de</strong> définir <strong>de</strong>s prototypes).<br />

VI.2. Prototypes<br />

Le prototypage permet d'indiquer au compilateur le type <strong>de</strong> donnée retourné par une fonction, ainsi que le nombre et le<br />

type <strong>de</strong>s arguments transmis ; Il s'agit donc en fait d'une déclaration <strong>de</strong> fonction.<br />

Cette déclaration permet au compilateur <strong>de</strong> réaliser <strong>de</strong>s contrôles (par exemple, il vérifie la cohérence <strong>de</strong>s paramètres<br />

transmis). Elle permet en outre la réalisation <strong>de</strong> transtypages automatiques, ce qui permet <strong>de</strong> lever bien <strong>de</strong>s erreurs.<br />

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

double sin(double);<br />

Ce prototype indique au compilateur que la fonction sinus retourne une valeur <strong>de</strong> type double et qu'elle attend un<br />

paramètre <strong>de</strong> type double.<br />

Ce prototype est défini en standard dans "math.h".<br />

Si ce prototype n'avait pas été défini, lors <strong>de</strong> l'écriture <strong>de</strong> la ligne<br />

y = sin(3);<br />

le nombre 3 écrit ainsi étant <strong>de</strong> type entier, la fonction sin attendant un double (dont le codage en mémoire est<br />

différent), la fonction ne récupérerait pas la valeur "3.0" ; Le résultat fourni par la fonction sin serait dans ce cas<br />

aléatoire.<br />

Il en va <strong>de</strong> même pour la valeur retournée, puisque le compilateur suppose par défaut qu'une fonction retourne un type<br />

int, ce qui n'est pas le cas dans cet exemple.<br />

Par contre, si le prototype est lu par le compilateur avant l'utilisation <strong>de</strong> la fonction, les transtypages se font <strong>de</strong> manière<br />

automatique, l'entier 3 <strong>de</strong>venant alors un nombre à virgule flottante (3.0) avant l'appel <strong>de</strong> la fonction.<br />

Pour éviter toute erreur, il est donc essentiel <strong>de</strong> déclarer les prototypes <strong>de</strong>s fonctions avant leur utilisation (ici, en<br />

ajoutant par exemple la ligne : #inclu<strong>de</strong> ).<br />

On notera que la définition d'un prototype ne génère pas <strong>de</strong> co<strong>de</strong> ; elle communique uniquement <strong>de</strong>s informations à<br />

l'attention du compilateur.<br />

VII. Blocs d'instructions<br />

Un bloc d'instructions est constitué soit :<br />

d'une instruction élémentaire terminée par un caractère ";"<br />

d'un ensemble d'instructions élémentaires encadrées par <strong>de</strong>s accola<strong>de</strong>s ; dans ce cas, le bloc d'instructions peut<br />

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

d'un simple caractère ';'. Dans ce cas, l'instruction est vi<strong>de</strong> (sans effet).<br />

Exemples <strong>de</strong> blocs d'instructions :<br />

ou :<br />

ou :<br />

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

{<br />

x = 2;<br />

y = 4;<br />

z = x+y;<br />

}<br />

{<br />

int i;<br />

i = 3;<br />

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

y=i;<br />

}<br />

-8-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

VII.1. Opérateurs<br />

Ils permettent l'évaluation d'expressions arithmétiques ou logiques.<br />

VII.1.a. Opérateurs arithmétiques :<br />

Opérateur Description Exemple (a=5, b=3, c=1)<br />

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

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

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

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

% modulo (reste <strong>de</strong> la division entière) x = 8%a x = 3<br />

^ ou exclusif (opération sur les bits) x = a^b x = 6<br />

| ou (opération sur les bits) x = a|b x = 7<br />

& et (opération sur les bits) x = a&b x = 1<br />

>c x = 1<br />

VII.1.b. Opérateurs logiques :<br />

Ils donnent comme résultat un entier (0 pour faux, 1 pour vrai).<br />

Opérateur Description Exemple (a=5, b=3)<br />

== test d'égalité x = a==b x = 0<br />

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

&& et logique x = (a>0) && (a4 x = 1<br />

=4 x = 1<br />

Remarques :<br />

- Lors <strong>de</strong> l'exécution, il se peut que <strong>de</strong>s termes ne soient pas évalués dans <strong>de</strong>s expressions logiques ; cela<br />

peut être le cas si le résultat final peut être déterminé avant l'évaluation totale <strong>de</strong> l'expression. Dans ce cas,<br />

il est donc fortement déconseillé d'utiliser <strong>de</strong>s appels <strong>de</strong> fonctions ou d'effectuer <strong>de</strong>s affectations sur <strong>de</strong>s<br />

variables à l'intérieur d'expressions logiques (le résultat dépendra <strong>de</strong> la façon dont le compilateur aura<br />

effectué la traduction <strong>de</strong> l'expression).<br />

Par exemple, lors <strong>de</strong> l'écriture <strong>de</strong> la ligne<br />

if ((a>5) || (somme(a,b)


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

|= équivalent à # = # | … a |= b a = 7<br />

&= équivalent à # = # & … a &= b a = 1<br />

>= b-2 a = 2<br />

Remarques :<br />

En C, l'affectation est un opérateur à part entière : Elle donne un résultat qui peut être utilisé dans une expression, ce qui<br />

permet les écritures suivantes :<br />

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

met 3 dans a et 4 dans x<br />

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

Il faut cependant noter que ces écritures concises risquent <strong>de</strong> rendre le programme moins lisible. D'autre part, il n'est pas<br />

certain que le co<strong>de</strong> généré soit amélioré par ce type d'écriture quelquefois plus difficile à interpréter par le compilateur ;<br />

Tout dépend <strong>de</strong> la puissance du compilateur.<br />

VII.1.d. Opérateur ternaire :<br />

Opérateur Description Exemple (a=5, b=3, c=1)<br />

: choix d'une valeur selon une condition<br />

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

si la condition est vraie, la première expression est<br />

retournée, sinon, la <strong>de</strong>uxième expression est retournée. x=(a3) x = 0<br />

++ auto incrémentation (post ou pré) x = a++ x = 5, a = 6<br />

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

-- auto décrémentation (post ou pré) x = a-- x = 5, a = 4<br />

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

sizeof donne la taille d'un objet (donnée ou type).<br />

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

sizeof(char) vaut 1<br />

sizeof sur un tableau donne le nombre d'octets occupé par le tableau<br />

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

(type) opérateur cast (transtypage). Permet <strong>de</strong> modifier le type d'une expression ; type représente un<br />

type <strong>de</strong> donnée prédéfini.<br />

Exemples :<br />

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

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

-10-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

VII.2. Expressions<br />

Les expressions utilisent <strong>de</strong>s opérateurs. L'ordre d'évaluation <strong>de</strong>s expressions dépend <strong>de</strong> la priorité <strong>de</strong>s opérateurs. Dans<br />

le doute, il est recommandé d'utiliser <strong>de</strong>s parenthèses.<br />

Exemples :<br />

3b<br />

x = 2*a + 3*b/4/c; est interprété comme : x 2<br />

a<br />

4 c<br />

La priorité <strong>de</strong>s opérateurs est indiquée ci-<strong>de</strong>ssous :<br />

Opérateurs<br />

Priorité<br />

() [] -> . 15<br />

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

* / % 13<br />

+ - 12<br />

> 11<br />

< >= 10<br />

== != 9<br />

& 8<br />

^ 7<br />

| 6<br />

&& 5<br />

|| 4<br />

: 3<br />

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

, 1<br />

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

VII.3. Instructions <strong>de</strong> contrôle <strong>de</strong> déroulement<br />

Les instructions <strong>de</strong> contrôle sont celles offertes par tous les langages évolués, avec toutefois une plus gran<strong>de</strong> souplesse<br />

procurée par l'écriture concise du langage.<br />

Toute expression retournant une valeur peut être utilisée lors <strong>de</strong> l'utilisation d'une condition ; Si le résultat (converti en<br />

int) est nul, la condition sera considérée comme fausse ; Elle sera vraie dans le cas contraire.<br />

VII.3.a. 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 />

optionnel<br />

VII.3.b. Boucles tant que … faire :<br />

while (condition)<br />

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

la condition est réévaluée à la fin <strong>de</strong> l'exécution du bloc d'instructions ; si<br />

la condition est vraie, le bloc est exécuté <strong>de</strong> nouveau (voir graphe cicontre).<br />

Exemple :<br />

while(x


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

VII.3.c. Boucles faire … tant que :<br />

Exemple :<br />

do<br />

bloc d'instructions à exécuter.<br />

while (condition);<br />

Le bloc d'instructions est exécuté inconditionnellement ; La condition<br />

est ensuite évaluée ; si la condition est vraie, le bloc est exécuté <strong>de</strong><br />

nouveau (voir graphe ci-contre).<br />

non<br />

bloc<br />

d'instructions<br />

condition<br />

vraie <br />

oui<br />

do<br />

{<br />

printf("Entrer un nombre positif : ");<br />

scanf("%d",&x);<br />

}<br />

while(x


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

do<br />

Exemple :<br />

{<br />

k = getchar(); /* Acquisition clavier -> k */<br />

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

{<br />

case '1':<br />

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

break; /* Quitter switch */<br />

case '2':<br />

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

break; /* Quitter switch */<br />

case 'q':<br />

case 'Q':<br />

printf("Fin du programme.\n"); /* Quitter le programme si */<br />

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

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

printf("\n"); /* Erreur */<br />

}<br />

}<br />

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

VII.3.f. Rupture <strong>de</strong> séquence break :<br />

break permet <strong>de</strong> sortir d'une boucle <strong>de</strong> type type while … , do … while , for ou d'un switch … case. On<br />

peut noter un exemple d'utilisation dans l'exemple précé<strong>de</strong>nt.<br />

VII.3.g. Rupture <strong>de</strong> séquence continue :<br />

continue permet d'interrompre le déroulement normal d'une boucle <strong>de</strong> type while … , do … while ou for<br />

en allant directement à la fin du bloc d'instructions.<br />

Exemple :<br />

for(i=0; i


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

VIII.1. Donnée globale au programme<br />

Pour qu'une donnée soit globale au programme, il<br />

suffit <strong>de</strong> la définir à l'extérieur d'un bloc <strong>de</strong> fonction.<br />

Pour y accé<strong>de</strong>r <strong>de</strong>puis un autre module, ou avant sa<br />

définition, il faut effectuer une déclaration <strong>de</strong> cette<br />

donnée avec le spécificateur extern, afin que le<br />

compilateur puisse connaître son existence.<br />

On note que par défaut, les noms <strong>de</strong>s fonctions sont<br />

globaux au programme ; les fonctions <strong>de</strong>s modules<br />

sont dont accessibles par la totalité <strong>de</strong>s modules.<br />

module 1<br />

...<br />

double x;<br />

...<br />

...<br />

x=2.0*a;<br />

module 2<br />

...<br />

extern double x;<br />

...<br />

...<br />

x = x+1.0;<br />

VIII.2. Donnée locale à un module<br />

Quelquefois, on souhaite définir une donnée globale à un ensemble <strong>de</strong> fonctions contenues dans un module, mais pas à<br />

la totalité du programme ; C'est notamment le cas lors <strong>de</strong> l'écriture <strong>de</strong> bibliothèques <strong>de</strong> fonctions dont on ne veut pas<br />

qu'un nom puisse interférer avec ceux <strong>de</strong> l'utilisateur <strong>de</strong> la bibliothèque.<br />

Pour rendre une donnée globale au module, il suffit <strong>de</strong> la déclarer à l'extérieur d'un corps <strong>de</strong> fonction en ajoutant le<br />

spécificateur static.<br />

Exemple :<br />

int x;<br />

x est globale au programme (et donc au module aussi)<br />

static double y;<br />

y est locale au module (inconnue <strong>de</strong>s autres modules)<br />

void fct1(void)<br />

{<br />

...<br />

}<br />

static void fct2(void)<br />

{<br />

...<br />

}<br />

la fonction fct1 est accessible par tout le programme<br />

la fonction fct2 n'est visible que dans ce module<br />

VIII.3. Donnée locale à une fonction<br />

Une donnée définie à l'intérieur d'un corps <strong>de</strong> fonction est locale à cette fonction et n'est donc accessible qu'à l'intérieur<br />

<strong>de</strong> cette fonction. On notera que les paramètres transmis à la fonction sont vus comme <strong>de</strong>s variables locales à cette<br />

fonction.<br />

Exemple :<br />

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

{<br />

unsigned c,d;<br />

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

...<br />

}<br />

VIII.4. Donnée locale à un bloc d'instructions<br />

En C, il est possible <strong>de</strong> déclarer <strong>de</strong>s données à l'intérieur d'un bloc d'instructions. Dans ce cas, ces données sont locales<br />

au bloc d'instructions.<br />

Exemple :<br />

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

{<br />

unsigned i;<br />

i est locale à la fonction<br />

...<br />

for(i=0; i


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

IX.1. static<br />

Ce mot clé signifie que la donnée doit être à allocation fixe pendant toute la durée d'exécution du programme ; il s'agit<br />

d'une donnée statique, dont l'adresse <strong>de</strong>meure inchangée pendant l'existence du programme.<br />

Remarques :<br />

Les données globales sont statiques, car elles existent dès le démarrage du programme.<br />

Déclarer une variable locale comme étant statique permet <strong>de</strong> retrouver sa valeur antérieure (lors du <strong>de</strong>rnier passage dans<br />

la fonction).<br />

Les variables statiques peuvent être initialisées ; on spécifie alors la valeur que doit prendre la variable lors du<br />

démarrage du programme.<br />

Une variable statique non initialisée est par défaut mise à zéro au démarrage du programme ; Ceci n'est cependant pas<br />

garanti sur tous les environnements.<br />

Exemple :<br />

void fonction(void)<br />

{<br />

{<br />

static x;<br />

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

static long double pi=3.14L; pi vaut 3.14 au démarrage du programme<br />

if(x


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

entrée. On <strong>de</strong>man<strong>de</strong> ainsi au compilateur <strong>de</strong> ne pas réaliser d'optimisation sur cette variable ; il <strong>de</strong>vra évaluer sa valeur à<br />

chaque accès, comme indiqué dans le programme.<br />

Exemple :<br />

...<br />

volatile char x;<br />

extern volatile unsigned char pio;<br />

...<br />

X. Les pointeurs<br />

X.1. Définition<br />

Les pointeurs permettent d'accé<strong>de</strong>r à <strong>de</strong>s données à partir <strong>de</strong> leur adresse.<br />

Notation :<br />

où<br />

et<br />

*nom_var<br />

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

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

Déclaration :<br />

nom_type *nom_var;<br />

Exemple :<br />

char *c;<br />

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

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

Certaines données sont constantes et l'utilisation <strong>de</strong> pointeurs pourrait autoriser la modification <strong>de</strong> ces données. Dans ce<br />

cas, les déclarations suivantes sont vali<strong>de</strong>s :<br />

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

pointeur sur une donnée constante : const char *c; (*c est constant)<br />

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

pointeur constant sur une donnée constante : const int * const p; (p et *p sont constants)<br />

X.2. Arithmétique <strong>de</strong>s pointeurs<br />

Les opérations suivantes sont vali<strong>de</strong>s :<br />

opérateur<br />

pointeur + entier<br />

pointeur - entier<br />

pointeur - pointeur<br />

pointeur comparaison pointeur<br />

résultat<br />

pointeur<br />

entier<br />

Lorsque l'on ajoute ou retranche un entier à un pointeur, on accè<strong>de</strong> à un élément positionné en mémoire comme s'il était<br />

dans un tableau. Par exemple, si p est un pointeur, les pointeurs (p+i) pointent sur les données situées à la suite <strong>de</strong> la<br />

donnée pointée par p, tandis que les pointeurs (p-i) pointent sur les données situées avant, comme indiqué ci-<strong>de</strong>ssous :<br />

…<br />

p-2<br />

p-1<br />

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

Le programme suivant peut ainsi être utilisé pour parcourir une chaîne <strong>de</strong> caractères :<br />

char *p, c;<br />

p = "HELLO";<br />

c = *p;<br />

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

p += 4;<br />

p--;<br />

c = 'H'<br />

c = 'E'<br />

*p = 'O'<br />

*p = 'L'<br />

Remarque :<br />

Quand on ajoute (ou retranche) un entier à un pointeur, l'adresse est augmentée (ou diminuée) <strong>de</strong> la taille (en octets, ou<br />

éléments <strong>de</strong> taille élémentaire) <strong>de</strong> l'élément pointé. C'est pourquoi le compilateur ne peut opérer <strong>de</strong>s opérations sur les<br />

-16-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

pointeurs que lorsqu'il connaît le type <strong>de</strong>s données pointées ; L'arithmétique <strong>de</strong>s pointeurs ne fonctionne donc pas avec<br />

<strong>de</strong>s pointeurs void.<br />

X.3. Utilité <strong>de</strong>s pointeurs<br />

En C, l'usage <strong>de</strong>s pointeurs est indispensable pour :<br />

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

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

permettre aux fonctions <strong>de</strong> retourner plusieurs valeurs<br />

X.3.a. Les tableaux<br />

Ils permettent <strong>de</strong> disposer <strong>de</strong> manière contiguë en mémoire <strong>de</strong>s données <strong>de</strong> même type. Par exemple, la tableau déclaré<br />

par :<br />

double v[5];<br />

place 5 variables en virgule flottante à partir <strong>de</strong> l'adresse v.<br />

v est donc un pointeur. Il est constant (sinon on perdrait l'adresse <strong>de</strong> base du tableau).<br />

v est l'adresse <strong>de</strong> la première donnée du tableau.<br />

Pour accé<strong>de</strong>r aux éléments du tableau, on utilise la notation v[i], où i est un entier et représente l'indice.<br />

En C, l'indice du premier élément d'un tableau est toujours 0. Ainsi, pour le tableau v contenant 5 éléments, on pourra<br />

accé<strong>de</strong>r aux éléments v[0] à v[4].<br />

Puisque v est un pointeur, on peut également accé<strong>de</strong>r à l'élément i du tableau en écrivant : *(v+i).<br />

Les notations v[i] et *(v+i) sont équivalentes ; Elles peuvent être utilisées même lorsque v n'est pas un tableau.<br />

Pour connaître l'espace mémoire occupé par un tableau, on peut utiliser l'opérateur sizeof sur ce tableau. Par exemple,<br />

dans le cas précé<strong>de</strong>nt, sizeof(v) donnerait 40 si le type double avait une taille <strong>de</strong> 8.<br />

Pour déterminer le nombre d'éléments que l'on peut mettre dans un tableau, on peut donc écrire l'expression suivante :<br />

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

On divise la taille du tableau par la taille du premier élément du tableau, ce qui donne le nombre d'éléments contenus (5<br />

dans l'exemple).<br />

Par contre, il faut bien noter que l'opérateur sizeof appliqué à un pointeur donne la taille du pointeur. Par exemple, avec<br />

la déclaration :<br />

char *str = "Hello";<br />

sizeof(str) donne la valeur 4 si les pointeurs occupent 4 octets. La déclaration ci-<strong>de</strong>ssus indique simplement que<br />

l'on définit un pointeur que l'on initialise sur une chaîne <strong>de</strong> caractères constante ("Hello").<br />

Quant à la déclaration suivante :<br />

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

l'utilisation <strong>de</strong> sizeof(str) dans ce cas donnera 10, car on a ici défini un tableau <strong>de</strong> 10 caractères, ce tableau étant<br />

initialisé par les 6 caractères <strong>de</strong> la chaîne "Hello" (y compris l'octet nul).<br />

X.3.b. Chaînes <strong>de</strong> caractères<br />

En C, les chaînes <strong>de</strong> caractères sont <strong>de</strong>s tableaux <strong>de</strong> caractères. Le caractère '\0' est le délimiteur <strong>de</strong> chaîne et sera pris<br />

en compte par toutes les fonctions traitant <strong>de</strong>s chaînes <strong>de</strong> caractères.<br />

Une chaîne <strong>de</strong> caractères constante sera notée entre guillemets, par exemple : "Bonjour à tous". Les caractères<br />

successifs sont placés en mémoire et l'octet nul est ajouté à la fin. La chaîne "toto" occupe donc 5 octets.<br />

On trouvera <strong>de</strong>s exemples d'initialisation <strong>de</strong> chaînes <strong>de</strong> caractères dans le paragraphe précé<strong>de</strong>nt.<br />

X.3.c. Fonctions et pointeurs<br />

Les fonctions retournent une valeur unique. Lorsque l'on désire qu'une fonction retourne plusieurs valeurs, on utilise <strong>de</strong>s<br />

pointeurs au niveau <strong>de</strong>s paramètres transmis à la fonction : On transmet ainsi les paramètres par référence.<br />

Exemple d'une fonction initialisant un tableau à 0 :<br />

void InitTab(int *baseTab, unsigned nb)<br />

{<br />

unsigned i;<br />

for(i=0; i


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

La fonction InitTab aurait pu également être écrite ainsi :<br />

void InitTab(int *baseTab, unsigned nb)<br />

{<br />

while(nb--) *(baseTab++)=0;<br />

}<br />

Les paramètres étant transmis à la fonction par valeur, et ces <strong>de</strong>rniers étant locaux à la fonction, leur modification dans<br />

la fonction ne change pas la valeur <strong>de</strong>s données transmises en arguments lors <strong>de</strong> l'appel.<br />

Par contre, on accè<strong>de</strong> aux éléments <strong>de</strong> tableau par l'intermédiaire <strong>de</strong> l'adresse du tableau.<br />

Autre exemple permettant la recherche <strong>de</strong> minima et maxima :<br />

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

{<br />

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

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

}<br />

...<br />

double tab[100];<br />

unsigned i;<br />

double mini, maxi;<br />

...<br />

mini = maxi = *tab;<br />

for(i=1; i


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

Remarque :<br />

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

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

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

XI.2. Flux en sortie.<br />

Par défaut lřécran (stdout) ne nécessite pas dřouverture.<br />

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

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

printf, fprintf, sprintf,…<br />

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

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

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

putchar, putc, fputc<br />

int putchar(int x)<br />

int putc(int x, FILE *f)<br />

int fputc(int 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 void *buffer, size_t size, size_t nb, FILE *f)<br />

XI.3. Flux en entrée.<br />

Par défaut le clavier (stdin) ne nécessite pas dřouverture.<br />

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

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

scanf, fscanf, sscanf,…<br />

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

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

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

getchar, getc, fgetc<br />

int getchar(void)<br />

int getc(FILE *f)<br />

int fgetc(FILE *f)<br />

gets, fgets<br />

char *gets(void)<br />

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

fread<br />

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

XI.4. Fonctions <strong>de</strong> gestion<br />

<br />

<br />

<br />

<br />

<br />

long ftell(FILE *f)<br />

int fseek(FILE *f, long offset, int fromwhere)<br />

void rewind(FILE *f)<br />

int feof(FILE *f)<br />

int fflush(FILE *f)<br />

XII. Fonctions standard<br />

XII.1. Manipulation <strong>de</strong> chaînes <strong>de</strong> caractères <br />

memchr strcat strchr strrstr<br />

memcmp strncat strrchr strlen<br />

memcpy strcpy strspn strerror<br />

memmove strncpy strcspn<br />

memset strcmp strpbrk<br />

strncmp<br />

strtok<br />

-19-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

XII.1.a. Traitement <strong>de</strong> données brutes<br />

memchr : recherche le caractère c dans les n premiers octets du tableau s.<br />

void *memchr(const void *s, int c, size_t n);<br />

Cette fonction retourne un pointeur sur la première occurence <strong>de</strong> c dans s ; elle retourne NULL si c ne figure pas<br />

dans le tableau s.<br />

memcmp : compare <strong>de</strong>ux blocs, s1 et s2, sur une longueur d'exactement n octets.<br />

int memcmp(const void *s1, const void *s2, size_t n);<br />

Cette fonction retourne une valeur < 0 si s1 est inférieur à s2, nulle si s1 est i<strong>de</strong>ntique à s2 et > 0 si s1 est supérieur à<br />

s2.<br />

memcpy : copie un bloc <strong>de</strong> n octets <strong>de</strong> src dans <strong>de</strong>st.<br />

void *memcpy(void *<strong>de</strong>st, const void *src, size_t n);<br />

Cette fonction retourne le pointeur <strong>de</strong>st.<br />

memmove : copie un bloc <strong>de</strong> n octets <strong>de</strong> src dans <strong>de</strong>st.<br />

void *memmove(void *<strong>de</strong>st, const void *src, size_t n);<br />

Cette fonction retourne le pointeur <strong>de</strong>st.<br />

memset : initialise n octets <strong>de</strong> s avec l'octet c.<br />

void *memset(void *s, int c, size_t n);<br />

Cette fonction retourne le pointeur s.<br />

XII.1.b. Copie et concaténation :<br />

strcat : concatène la chaîne src à <strong>de</strong>st.<br />

char *strcat(char *<strong>de</strong>st, const char *src);<br />

Cette fonction retourne <strong>de</strong>st.<br />

strncat : ajoute au plus maxlen caractères <strong>de</strong> la chaîne src à la fin <strong>de</strong> <strong>de</strong>st.<br />

char *strncat(char *<strong>de</strong>st, const char *src, size_t maxlen);<br />

Cette fonction retourne <strong>de</strong>st.<br />

strcpy : copie la chaîne src dans <strong>de</strong>st.<br />

char *strcpy(char *<strong>de</strong>st, const char *src);<br />

Cette fonction retourne l'adresse <strong>de</strong> <strong>de</strong>st.<br />

strncpy : copie jusqu'à maxlen caractères <strong>de</strong> la chaîne src dans la chaîne <strong>de</strong>st.<br />

char *strncpy(char *<strong>de</strong>st, const char *src, size_t maxlen);<br />

Si maxlen caractères sont copiés, aucun caractère nul n'est ajouté ; le contenu <strong>de</strong> la zone <strong>de</strong>st est une chaîne terminée<br />

par un caractère nul.<br />

Cette fonction retourne <strong>de</strong>st.<br />

XII.1.c. Comparaisons <strong>de</strong> chaînes <strong>de</strong> caractères :<br />

strcmp : compare la chaîne s2 à la chaîne s1.<br />

int strcmp(const char *s1, const char *s2);<br />

Cette fonction retourne une valeur < 0 si s1 est inférieur à s2, nulle si s1 est i<strong>de</strong>ntique à s2 et > 0 si s1 est supérieur à<br />

s2. La comparaison est signée.<br />

-20-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

strncmp : compare les chaînes s2 et s1 en se limitant aux maxlen premiers caractères.<br />

int strncmp(const char *s1, const char *s2, size_t maxlen);<br />

Cette fonction retourne une valeur < 0 si s1 est inférieur à s2, nulle si s1 est i<strong>de</strong>ntique à s2 et > 0 si s1 est supérieur à<br />

s2. Effectue une comparaison signée.<br />

XII.1.d. Recherche <strong>de</strong> séquences :<br />

strchr : cherche le caractère c dans la chaîne str.<br />

char *strchr(const char *str, int c);<br />

Cette fonction retourne un pointeur sur la première occurrence du caractère c dans str ; si c ne figure pas dans str,<br />

strchr retourne NULL.<br />

strrchr : cherche dans la chaîne s la <strong>de</strong>rnière occurrence du caractère c.<br />

char *strrchr(const char *s, int c);<br />

Cette fonction retourne un pointeur sur la <strong>de</strong>rnière occurrence du caractère c dans s ; si c ne figure pas dans la<br />

chaîne, elle retourne NULL.<br />

strspn : cherche la longueur du segment initial <strong>de</strong> s1 formé uniquement <strong>de</strong> caractères figurant dans la chaîne s2.<br />

size_t strspn(const char *s1, const char *s2);<br />

strcspn : cherche la longueur du premier segment <strong>de</strong> s1 formé uniquement <strong>de</strong> caractères NE FIGURANT PAS dans la<br />

chaîne s2.<br />

size_t strcspn(const char *s1, const char *s2);<br />

strpbrk : cherche dans la chaîne s1 la première occurrence d'un caractère quelconque <strong>de</strong> la chaîne s2.<br />

char *strpbrk(const char *s1, const char *s2);<br />

Cette fonction retourne un pointeur sur la première occurrence dans s1 d'un caractère <strong>de</strong> s2 ; si aucun <strong>de</strong>s caractères<br />

<strong>de</strong> s2 ne figure dans s1, c'est la valeur NULL qui est retournée.<br />

strstr : cherche la première occurrence <strong>de</strong> la sous-chaîne s2 dans s1.<br />

char *strstr(const char *s1, const char *s2);<br />

Cette fonction retourne un pointeur sur la partie <strong>de</strong> s1 i<strong>de</strong>ntique à s2 (un pointeur sur s2 dans s1). S'il n'y a pas<br />

d'occurrence <strong>de</strong> s2 dans s1, c'est la valeur NULL qui est retournée.<br />

strtok : cherche dans la chaîne s1 le premier élément ne figurant pas dans s2.<br />

char *strtok(char *s1, const char *s2);<br />

s2 définit <strong>de</strong>s caractères séparateurs. strtok considère la chaîne s1 comme une suite d'éléments séparés par <strong>de</strong>s<br />

caractères <strong>de</strong> la chaîne s2. Si aucun élément n'est trouvé dans s1, la fonction retourne la valeur NULL. Si un élément<br />

est trouvé, le caractère nul est écrit dans s1 à la suite <strong>de</strong> l'élément et strtok retourne un pointeur sur cet élément.<br />

Les appels suivants à strtok avec NULL comme premier argument poursuivent la recherche dans la chaîne s1 <strong>de</strong><br />

l'appel précé<strong>de</strong>nt et continuent après le <strong>de</strong>rnier élément trouvé.<br />

XII.1.e. Fonctions diverses :<br />

strlen : calcule la longueur <strong>de</strong> la chaîne s.<br />

size_t strlen(const char *s);<br />

Cette fonction retourne le nombre <strong>de</strong> caractères <strong>de</strong> la chaîne s, le caractère nul d'arrêt n'étant pas compté.<br />

strerror : retourne un pointeur sur une chaîne contenant un message d'erreur.<br />

char *strerror(int errnum);<br />

Cette fonction retourne un pointeur sur le message d'erreur associé à errnum.<br />

-21-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

XII.2. Entrées sorties <br />

clearerr getc flushall rewind<br />

fclose getchar fopen scanf<br />

fcloseall gets fprintf setbuf<br />

fdopen getw fputc setvbuf<br />

feof perror fputchar sprintf<br />

ferror printf fputs scanf<br />

fflush putcs fread _strerror<br />

fgetc putchar freopen strerror<br />

fgetchar puts fscanf vfscanf<br />

fgetpos tmpfile fseek vprintf<br />

fgets tmpnam fsetpos vscanf<br />

fileno ungetc putw vsprintf<br />

ftell unlink remove vsscanf<br />

fwrite vfprintf rename<br />

XII.2.a. Entrées / Sorties formatées :<br />

scanf : effectue <strong>de</strong>s entrées formatées <strong>de</strong>puis le flux standard stdin<br />

int scanf(const char *format, ...);<br />

Cette fonction retourne le nombre <strong>de</strong> champs d'entrée traités correctement. Elle traite les entrées selon la chaîne <strong>de</strong><br />

format et place les résultats dans les emplacements mémoire pointés par les arguments.<br />

printf : écrit <strong>de</strong>s sorties formatées dans le flux standard stdout.<br />

int printf(const char *format, ...);<br />

Cette fonction applique une spécification <strong>de</strong> format à un nombre variable d'arguments et écrit les données formatées<br />

dans le flux stdout. printf retourne le nombre d'octets écrits. En cas d'erreur, elle retourne EOF.<br />

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

% [flags] [width] [.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 />

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

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

g : format e ou f suivant la précision<br />

E : comme e mais l'exposant est la lettre E<br />

G : comme g mais l'exposant est la lettre E<br />

c : caractère simple<br />

s : affiche les caractères jusqu'au caractère nul d'arrêt '\0' ou jusqu'à ce que la précision soit 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 écrits.<br />

[flags] Signification<br />

aucun : résultat justifié à droite et complété à gauche par <strong>de</strong>s espaces ou <strong>de</strong>s 0<br />

- : résultat justifié à gauche et complété à droite par <strong>de</strong>s espaces<br />

+ : les résultats commencent toujours par le signe + ou -<br />

espace : 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 : sans effet<br />

-22-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

o : 0 sera placé <strong>de</strong>vant l'argument s'il est non nul<br />

x ou X : 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 : même chose mais sans les zéros à droite<br />

[width] Effet sur l'affichage<br />

n : affichage d'au moins n caractères, au besoin complété par <strong>de</strong>s espaces<br />

0n : affichage d'au moins n caractères, au besoin complété à gauche par <strong>de</strong>s chiffres 0<br />

* : l'argument suivant <strong>de</strong> la liste contient la spécification <strong>de</strong> largeur<br />

[.prec] Effet sur l'affichage<br />

aucun : 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 />

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 d,i,o,u,x,X<br />

l : arg est interprété comme un entier <strong>de</strong> type long pour d,i,o,u,x,X<br />

l : arg est interprété comme un réel <strong>de</strong> type double pour e,E,f,g,G (scanf)<br />

L : arg est interprété comme un réel <strong>de</strong> type long double pour e,E,f,g,G<br />

XII.2.c. Fonctions d'entrées :<br />

getchar : (macro) retourne un caractère <strong>de</strong>puis le flux d'entrée stdin.<br />

int getchar(void);<br />

getchar retourne le caractère lu, après conversion en un entier <strong>de</strong> type int sans extension <strong>de</strong> signe. Elle retourne EOF à la<br />

fin du fichier ou en cas d'erreur.<br />

getc : (macro) retourne un caractère <strong>de</strong>puis un flux.<br />

int getc(FILE *fp);<br />

Cette macro retourne le caractère lu. Elle retourne EOF à la fin du fichier ou en cas d'erreur.<br />

fgets : lit une chaîne dans un flux.<br />

char *fgets(char *s, int n, FILE *fp);<br />

Lorsqu'elle réussit, cette fonction retourne la chaîne s ; elle retourne NULL en fin <strong>de</strong> fichier ou en cas d'erreur.<br />

XII.2.d. Fonctions <strong>de</strong> sorties :<br />

putchar : envoie un caractère dans le flux standard stdout.<br />

int putchar(int ch);<br />

Si la sortie peut se faire, putchar retourne le caractère ch ; s'il y a une erreur, elle retourne EOF.<br />

putc : sort un caractère dans un flux.<br />

int putc(int ch, FILE *fp);<br />

Si la sortie peut se faire, putc retourne le caractère ch ; s'il y a une erreur, elle retourne EOF.<br />

fputs : envoie une chaîne dans un flux.<br />

int fputs(const char *s, FILE *fp);<br />

S'il n'y a pas d'erreur, cette fonction retourne le <strong>de</strong>rnier caractère écrit ; sinon, c'est la valeur EOF qui est retournée.<br />

-23-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

XII.2.e. Gestion <strong>de</strong> fichiers (flux) :<br />

fopen : ouvre un flux.<br />

FILE *fopen(const char *filename, const char *mo<strong>de</strong>);<br />

Si elle aboutit, cette fonction retourne un pointeur sur le flux qui vient d'être ouvert ; sinon, elle retourne NULL.<br />

Types d'ouverture :<br />

r : ouvert pour lecture<br />

w : créé pour écriture<br />

a : ouvert pour écriture en fin <strong>de</strong> fichier<br />

+ : pour permettre un accès en lecture et en écriture<br />

b : ouvert en mo<strong>de</strong> binaire<br />

t : ouvert en mo<strong>de</strong> texte<br />

fclose : ferme un flux.<br />

int fclose(FILE *fp);<br />

Cette fonction retourne 0 si elle réussit et EOF lorsqu'une erreur est détectée.<br />

fflush : vi<strong>de</strong> la mémoire tampon associée à un flux.<br />

int fflush(FILE *fp);<br />

Cette fonction retourne EOF lorsqu'une erreur est détectée.<br />

fseek : repositionne le pointeur <strong>de</strong> fichier d'un flux.<br />

int fseek(FILE *fp, long offset, int whence);<br />

offset est le nouvelle position par rapport l'emplacement donné par whence. Cette fonction retourne 0 si le pointeur a<br />

pu être déplacé et une valeur non nulle sinon.<br />

Constantes symboliques :<br />

Positionnement du pointeur <strong>de</strong> fichier.<br />

SEEK_SET au début du fichier<br />

SEEK_CUR à la position courante du pointeur<br />

SEEK_END à la fin du fichier<br />

fsetpos : positionne le pointeur <strong>de</strong> fichier d'un flux.<br />

int fsetpos(FILE *fp, const fpos_t *pos);<br />

Le nouvel emplacement pointé par pos est la valeur obtenue lors d'un précé<strong>de</strong>nt appel à fgetpos. Quand l'opération<br />

aboutit, cette fonction retourne 0. Dans le cas contraire, elle retourne une valeur non nulle.<br />

Rem. : fpos_t : Type pour les pointeurs <strong>de</strong> fichiers.<br />

ftell : retourne la position courante du pointeur d'un fichier.<br />

long ftell(FILE *fp);<br />

Cette fonction retourne la position courante du pointeur <strong>de</strong> fichier ou la valeur -1L quand il y a une erreur.<br />

fwrite : écrit dans un flux.<br />

size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);<br />

fwrite écrit n objets ayant chacun une longueur <strong>de</strong> size octets. Cette fonction retourne le nombre d'objets (et non le<br />

nombre d'octets) réellement écrits.<br />

fread : lit <strong>de</strong>s données <strong>de</strong>puis un flux.<br />

size_t fread(void *ptr, size_t size, size_t n, FILE *fp);<br />

Cette fonction lit n objets ayant chacun une longueur <strong>de</strong> size octets ; elle retourne le nombre d'objets (et non le<br />

nombre d'octets) réellement lus.<br />

-24-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

XII.2.f. Exemple : copie <strong>de</strong> fichier texte<br />

#inclu<strong>de</strong> <br />

#inclu<strong>de</strong> <br />

#inclu<strong>de</strong> <br />

void erreur(int err, const char *fmt, ...)<br />

{<br />

va_list arg;<br />

va_start(arg,fmt);<br />

fprintf(st<strong>de</strong>rr,"Erreur [%d] : ",err);<br />

vfprintf(st<strong>de</strong>rr,fmt,arg);<br />

va_end(arg);<br />

exit(err);<br />

}<br />

main(int argc, char *argv[])<br />

{<br />

FILE *fs, *fd ;<br />

int x ;<br />

if(argc>1)<br />

{<br />

fs=fopen(argv[1],"r");<br />

if(fs==NULL) erreur(1,"Le fichier %s ne peut être ouvert.\n",argv[1]);<br />

}<br />

else fs=stdin;<br />

if(argc>2)<br />

{<br />

fd=fopen(argv[2],"w");<br />

if(fd==NULL) erreur(2,"Création <strong>de</strong> %s impossible.\n",argv[1]);<br />

}<br />

else fd=stdout;<br />

while((x=getc(fs))!=EOF)<br />

if(putc(x,fd)==EOF) erreur(3,"Erreur en écriture");<br />

fclose(fd);<br />

fclose(fs);<br />

return 0;<br />

}<br />

XII.3. Fonctions utilitaires :<br />

atof rand bsearch calloc abort abs<br />

atoi srand qsort malloc exit labs<br />

atol realloc atexit div<br />

strtod free system ldiv<br />

strtol<br />

getenv<br />

strtoul<br />

XII.3.a. Conversion <strong>de</strong> chaînes <strong>de</strong> caractères :<br />

atof : convertit une chaîne <strong>de</strong> caractères en un nombre à virgule flottante.<br />

double atof(const char *s);<br />

Cette fonction retourne le résultat <strong>de</strong> la conversion ou 0 si s ne peut pas être convertie.<br />

atoi : convertit une chaîne en un entier<br />

int atoi(const char *s);<br />

Retourne le résultat <strong>de</strong> la conversion <strong>de</strong> la chaîne passée en argument. Si la chaîne ne peut pas être convertie, la<br />

valeur retournée est 0.<br />

atol : convertit une chaîne <strong>de</strong> caractères en un entier long.<br />

long atol(const char *s);<br />

Cette fonction retourne le résultat <strong>de</strong> la conversion en entier <strong>de</strong> la chaîne passée en argument. Si la chaîne ne peut<br />

pas être convertie, la valeur retournée est 0.<br />

-25-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

strtod : convertit une chaîne en une valeur <strong>de</strong> type double.<br />

double strtod(const char *s, char **endptr);<br />

Cette fonction retourne la valeur <strong>de</strong> la chaîne s convertie en une valeur <strong>de</strong> type double. s doit être une suite <strong>de</strong><br />

caractères correspondant au format :<br />

[ws] [sn] [ddd] [.] [ddd] [fmt[sn]ddd]<br />

strtol : convertit la chaîne s en une valeur <strong>de</strong> type long, exprimée dans la base indiquée par radix.<br />

long strtol(const char *s, char **endptr, int radix);<br />

Cette fonction retourne la valeur convertie <strong>de</strong> la chaîne s ou bien 0 en cas d'erreur. s doit être une suite <strong>de</strong> caractères<br />

correspondant au format :<br />

[ws] [sn] [0] [x] [ddd]<br />

strtoul : convertit une chaîne en une valeur <strong>de</strong> type unsigned long, exprimée dans la base indiquée par radix.<br />

unsigned long strtoul(const char *s, char **endptr, int radix);<br />

Cette fonction retourne la valeur convertie <strong>de</strong> la chaîne ou bien 0 en cas d'erreur.<br />

XII.3.b. Générateur <strong>de</strong> nombres aléatoires :<br />

rand : générateur <strong>de</strong> nombres aléatoires.<br />

int rand(void);<br />

Cette fonction retourne un nombre aléatoire compris entre 0 et RAND_MAX. RAND_MAX est défini dans stdlib.h.<br />

srand : initialise le générateur <strong>de</strong> nombres aléatoires.<br />

void srand(unsigned seed);<br />

srand ne retourne pas <strong>de</strong> valeur.<br />

XII.3.c. Fouilles et tris :<br />

bsearch : recherche dichotomique dans un tableau (binary search).<br />

void *bsearch(const void *key, const void *base, size_t *nelem, size_t width,<br />

int (*fcmp)(const void*, const void*));<br />

bsearch retourne l'adresse du premier élément du tableau correspondant à la clé <strong>de</strong> recherche key. Si aucun élément<br />

ne convient, elle retourne 0.<br />

Dans bsearch, la valeur retournée par *fcmp est < 0 si *elem1 < *elem2, nulle si *elem1 est égal à *elem2 et > 0 if<br />

*elem1 > *elem2.<br />

Le tableau doit être trié en ordre croissant.<br />

qsort : effectue un tri rapi<strong>de</strong> (Quicksort).<br />

void qsort(void *base, size_t nelem, size_t width,<br />

int(*fcmp)(const void *, const void *));<br />

Cette fonction effectue le tri <strong>de</strong>s nelem éléments <strong>de</strong> taille width, situés dans le tableau pointé par base.<br />

XII.3.d. Allocation <strong>de</strong> mémoire :<br />

calloc : alloue <strong>de</strong> la mémoire.<br />

void *calloc(size_t nelem, size_t elsize);<br />

Alloue un bloc pour nelem items formés <strong>de</strong> elsize octets ; initialise le bloc avec <strong>de</strong>s zéros. Cette fonction retourne un<br />

pointeur sur le bloc nouvellement alloué ou la valeur NULL lorsqu'il n'y a pas assez <strong>de</strong> place.<br />

malloc : alloue <strong>de</strong> la mémoire.<br />

void *malloc(size_t size);<br />

L'argument size est exprimé en octets. Cette fonction retourne un pointeur sur le bloc nouvellement alloué, ou bien<br />

la valeur NULL quand il n'y a pas assez d'espace pour un nouveau bloc. Si size = 0, elle retourne NULL.<br />

-26-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

realloc : réalloue <strong>de</strong> la mémoire.<br />

void *realloc(void *block, size_t size);<br />

Cette fonction tente d'ajuster (augmenter ou diminuer) la taille d'un bloc précé<strong>de</strong>mment alloué pour l'amener à une<br />

taille <strong>de</strong> size octets. Elle retourne l'adresse du bloc réajusté qui n'est pas toujours la même que le bloc d'origine. Si<br />

l'opération n'a pas été possible ou si size vaut 0, elle retourne la valeur NULL.<br />

free : libère <strong>de</strong>s blocs alloués par malloc ou calloc.<br />

void free(void *block);<br />

XII.3.e. Fonctions système :<br />

abort : arrêt anormal d'un programme.<br />

void abort(void);<br />

exit : met fin à un programme.<br />

void exit(int status);<br />

Avant la sortie, les mémoires tampons sont vidées, les fichiers sont fermés et les fonctions <strong>de</strong> sortie sont appelées.<br />

atexit : enregistre une fonction <strong>de</strong> sortie.<br />

int atexit(atexit_t func);<br />

Cette fonction retourne 0 si l'enregistrement <strong>de</strong> la fonction peut avoir lieu et une valeur non nulle en cas d'anomalie.<br />

system : lance une comman<strong>de</strong> du système d'exploitation.<br />

int system(const char *command);<br />

system exécute une comman<strong>de</strong> du système d'exploitation<br />

Cette fonction retourne zéro si l'opération a pu se réaliser et -1 sinon.<br />

getenv : retourne un élément <strong>de</strong> l'environnement.<br />

char *getenv(const char *name);<br />

Si l'opération est possible, cette fonction retourne un pointeur sur la valeur associée à son argument name ; si le nom<br />

n'est pas défini dans l'environnement, retourne NULL.<br />

XII.3.f. Opérations sur <strong>de</strong>s entiers :<br />

abs : retourne la valeur absolue d'un entier.<br />

int abs(int x);<br />

labs : valeur absolue pour <strong>de</strong>s valeurs <strong>de</strong> type long.<br />

long labs(long x);<br />

div : divise <strong>de</strong>ux entiers.<br />

ldiv : divise <strong>de</strong>ux entiers <strong>de</strong> type long.<br />

div_t div(int numer, int <strong>de</strong>nom);<br />

ldiv_t ldiv(long lnumer, long l<strong>de</strong>nom);<br />

Chaque fonction retourne une structure dont les éléments sont quotient (quot) et le reste (rem). Les éléments sont<br />

<strong>de</strong>s entiers pour div et <strong>de</strong>s entiers longs pour ldiv.<br />

Type div_t : Type <strong>de</strong>s valeurs retournées par la fonction <strong>de</strong> division entière.<br />

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

{<br />

int quot, rem;<br />

} div_t;<br />

Type ldiv_t : Type <strong>de</strong>s valeurs retournées par la fonction <strong>de</strong> division entre entiers longs.<br />

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

{<br />

long quot, rem;<br />

} ldiv_t;<br />

-27-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

XIII. Structures<br />

Ces données sont construites par le programmeur à partir <strong>de</strong>s données déjà définies (par le langage ou le programmeur).<br />

Les structures permettent au programmeur <strong>de</strong> rassembler dans une même donnée un ensemble dřinformations liées.<br />

Par exemple, on souhaite se constituer un fichier dřindividus contenant le nom, le prénom, lřage et le poids pour chaque<br />

individu ; Ces informations étant propres à chaque individu, on préfère constituer une donnée unique contenant<br />

lřensemble <strong>de</strong> ces informations ; Cette nouvelle donnée sřappelle en C une structure.<br />

On pourra déclarer cette structure <strong>de</strong> la manière suivante :<br />

struct T_Individu<br />

{<br />

char nom[40] ;<br />

char prenom[40] ;<br />

unsigned age ;<br />

float poids;<br />

} ;<br />

champs <strong>de</strong> la structure<br />

struct : mot clé définissant une structure<br />

T_Individu : Nom du type <strong>de</strong> structure défini par le<br />

programmeur.<br />

Cette structure est composée <strong>de</strong> quatre champs (nom, prénom, âge et poids).<br />

Avec cette définition, on a défini un type <strong>de</strong> donnée (<strong>de</strong> type struct T_Individu). On peut alors définir <strong>de</strong> nouvelles<br />

données dans ce type :<br />

struct T_Individu toto ;<br />

struct T_Individu x, individu[20] ;<br />

Dans cet exemple, toto représente une variable contenant le nom, le prénom, lřâge et le poids dřun individu.<br />

Pour accé<strong>de</strong>r à un champ <strong>de</strong> la variable toto, on utilise le caractère Ř.ř.<br />

On pourra ainsi écrire :<br />

printf("Entrer le nom : ") ;<br />

scanf("%s",toto.nom) ;<br />

toto.age=4 ;<br />

toto.poids=12.3 ;<br />

On peut mettre les structures sous forme <strong>de</strong> tableaux avec une déclaration du type :<br />

struct T_Individu individu[20] ;<br />

Dans ce cas, on peut accé<strong>de</strong>r à lřélément i du tableau en écrivant individu[i], soit, par exemple pour son âge,<br />

individu[i].age, comme dans lřexemple suivant :<br />

printf("Entrer le nom n°%d : ",n) ;<br />

scanf("%s",toto[n].nom) ;<br />

scanf("%u",&toto[n].age) ;<br />

scanf("%f",&toto[n].poids) ;<br />

printf("%s : %u ans (%f kg)\n",toto[n].nom,toto[n].age,toto[n].poids) ;<br />

Il est possible <strong>de</strong> définir une structure sans définir un type <strong>de</strong> structure avec la déclaration suivante :<br />

struct<br />

{<br />

int forme ;<br />

double perimetre ;<br />

double aire ;<br />

} objet[200], rectangle, disque;<br />

Dans ce cas, il est bien sûr nécessaire <strong>de</strong> définir une ou plusieurs variables.<br />

On peut initialiser les structures par la notation suivante :<br />

struct T_Individu Homme =<br />

{<br />

"Dupont",<br />

"Marcel",<br />

24,<br />

84.5<br />

} ;<br />

Cette initialisation peut se faire dans les classes dřallocation const, static ou auto (attention alors à lřefficacité du<br />

programme).<br />

Les structures étant <strong>de</strong>s données <strong>de</strong> taille importante, il est plus efficace <strong>de</strong> les transmettre aux fonctions par<br />

lřintermédiaire <strong>de</strong> pointeurs :<br />

-28-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

Exemple :<br />

struct T_Complexe {double re, im ; } ;<br />

double module(struct T_Complexe *x)<br />

{<br />

return (*x).re*(*x).re+(*x).im*(*x).im;<br />

}<br />

Lřusage <strong>de</strong>s pointeurs étant fréquent avec les structures et cette notation étant lour<strong>de</strong> et peu lisible, le C a défini une<br />

autre notation lors <strong>de</strong> lřutilisation <strong>de</strong> pointeurs <strong>de</strong> structures :<br />

double module(struct T_Complexe *x)<br />

{<br />

return x->re* x->re + x->im * x->im;<br />

}<br />

x->re se lit : le champ re <strong>de</strong> la structure pointée par x.<br />

XIV. Le préprocesseur<br />

Le préprocesseur est un programme invoqué automatiquement par le compilateur avant la réalisation <strong>de</strong> la compilation.<br />

Son rôle est dřeffectuer <strong>de</strong>s transformations sur le fichier source. Cřest en réalité le fichier texte créé qui sera transmis<br />

au compilateur.<br />

Les comman<strong>de</strong>s du préprocesseur débutent par le caractère Ř#ř. Elles occupent toute la ligne débutant par Ř#ř et ne sont<br />

pas terminées par Ř ;ř. On peut les étendre sur plusieurs lignes en ayant recours au caractère dřéchappement Ř\ř situé en<br />

fin <strong>de</strong> ligne.<br />

XIV.1. Comman<strong>de</strong> inclu<strong>de</strong>.<br />

#inclu<strong>de</strong> <br />

ou<br />

#inclu<strong>de</strong> "fichier2"<br />

Permet <strong>de</strong> substituer en lieu et place <strong>de</strong> la comman<strong>de</strong> le contenu du fichier désigné.<br />

Les caractères Řř indiquent au préprocesseur <strong>de</strong> rechercher dans les répertoires pris par défaut par le compilateur (en<br />

général les fichiers dřen-tête livrés avec le compilateur). Si le fichier nřa pas été trouvé, il sera recherché dans le<br />

répertoire <strong>de</strong> travail courant.<br />

Les caractères Ř""ř <strong>de</strong>man<strong>de</strong>nt au préprocesseur <strong>de</strong> rechercher dans le répertoire <strong>de</strong> travail courant. Le programmeur<br />

utilise en général cette notation pour inclure les fichiers ".h" conçus par lui-même.<br />

XIV.2. Comman<strong>de</strong> <strong>de</strong>fine.<br />

Cette comman<strong>de</strong> permet <strong>de</strong> définir <strong>de</strong>s constantes ou <strong>de</strong>s macro-définitions.<br />

Constantes :<br />

Exemple :<br />

#<strong>de</strong>fine PI 3.14159265<br />

Macro-définitions :<br />

On définit ici la constante PI en indiquant sa valeur (sans Ř ;ř ni Ř=ř,…).<br />

Par la suite, à chaque fois que le préprocesseur voit une donnée se nommant PI, il la substitue par sa<br />

valeur (en réalisant une substitution <strong>de</strong> texte).<br />

Exemple :<br />

x = 3 * PI / 4 ;<br />

sera remplacé par :<br />

x = 3 * 3.14159265 / 4 ; (cette ligne sera effectivement lue par le compilateur).<br />

Il est très important <strong>de</strong> ne pas mettre <strong>de</strong> Ř ;ř en fin <strong>de</strong> <strong>de</strong>fine, sinon, le compilateur lirait :<br />

x = 3 * 3.14159265 ; / 4 ;<br />

ce qui provoquerait évi<strong>de</strong>mment une erreur à la compilation sur la ligne :<br />

x = 3 * PI / 4 ;<br />

qui paraît syntaxiquement correcte.<br />

Les macro-définitions permettent <strong>de</strong> réaliser <strong>de</strong>s pseudo-fonctions avec une transmission <strong>de</strong> paramètres<br />

ressemblant à celui utilisé dans les fonctions. Le fonctionnement est cependant totalement différent,<br />

puisque les paramètres seront utilisés pour réaliser <strong>de</strong>s substitutions <strong>de</strong> texte. Ce dispositif sera donc<br />

-29-


LICENCE SPI-EEA LANGAGE C M. <strong>Deloizy</strong><br />

beaucoup plus efficace en terme <strong>de</strong> rapidité dřexécution ; Par contre, la taille du co<strong>de</strong> généré sera plus<br />

importante.<br />

Exemple :<br />

#<strong>de</strong>fine produit(a,b) a*b<br />

On pourra ensuite utiliser la macro-fonction produit <strong>de</strong> la manière suivante :<br />

y = produit(3.0,4) ;<br />

Le premier paramètre (a) sera remplacé par (3.0), et le second (b) par (4). Le compilateur verra donc la<br />

ligne :<br />

y = 3.0*4 ;<br />

On peut utiliser la macro-fonction produit avec <strong>de</strong>s expressions plus compliquées :<br />

y = produit(3+1,4*2) ;<br />

ce qui sera transposé par :<br />

y = 3+1*4*2 ;<br />

qui, compte tenu <strong>de</strong> la priorité <strong>de</strong>s opérateurs, donne comme résultat 11 au lieu <strong>de</strong> 32 attendu.<br />

Pour éviter ce type <strong>de</strong> problème, il est préférable dřencadrer lřexpression et les paramètres par <strong>de</strong>s<br />

parenthèses lors <strong>de</strong> la définition <strong>de</strong> macro-fonctions :<br />

#<strong>de</strong>fine produit(a,b) ((a)*(b))<br />

Ainsi, la substitution <strong>de</strong> texte donnera la ligne suivante :<br />

y = ((3+1)*(4*2)) ;<br />

qui est cette fois correcte.<br />

XIV.3. Compilation conditionnelle<br />

La compilation conditionnelle permet au programmeur dřexclure ou non <strong>de</strong>s lignes <strong>de</strong> programmes selon la valeur ou<br />

lřexistence <strong>de</strong> constantes.<br />

Exemples :<br />

#if test==1<br />

… lignes source C 1<br />

#else<br />

… lignes source C 2<br />

#endif<br />

optionnel<br />

Les lignes « source C 1 » seront compilées si la constante test vaut 1. Sinon, seules les lignes « source C 2 » seront<br />

compilées.<br />

On peut également utiliser à la place <strong>de</strong> la comman<strong>de</strong> if les comman<strong>de</strong>s :<br />

#if<strong>de</strong>f nom_<strong>de</strong>_constante<br />

#ifn<strong>de</strong>f nom_<strong>de</strong>_constante<br />

Ces comman<strong>de</strong>s permettent <strong>de</strong> tester lřexistence ou non dřune constante et <strong>de</strong> compiler ou non la suite.<br />

Exemples :<br />

#ifn<strong>de</strong>f DEJA_COMP<br />

#<strong>de</strong>fine DEJA_COMP<br />

…<br />

#endif<br />

#if __TURBOC__<br />

#inclu<strong>de</strong> <br />

#endif<br />

Permet <strong>de</strong> ne pas compiler plusieurs fois la même section <strong>de</strong><br />

programme (utile lors <strong>de</strong> l’inclusion <strong>de</strong> fichiers).<br />

Détection <strong>de</strong> la "signature" du compilateur afin d’inclure un<br />

fichier d’en-tête non portable.<br />

-30-


LICENCE SPI-EEA TRAVAUX DIRIGÉS M. <strong>Deloizy</strong><br />

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 octet 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 />

Mettre le résultat en binaire, hexadécimal et 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 (nombre <strong>de</strong><br />

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 m2<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 et 5.0.<br />

Quelle est la valeur positive la plus petite 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 et 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'octets nécessaire au stockage du tableau <br />

-31-


LICENCE SPI-EEA TRAVAUX DIRIGÉS M. <strong>Deloizy</strong><br />

I. Écrire un programme affichant « BONJOUR » à lřécran.<br />

TD2 : PREMIERS PROGRAMMES<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 transmet le numéro <strong>de</strong> la table à<br />

afficher :<br />

void mult(int table)<br />

Utiliser cette 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 visualiser. Le<br />

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> cette fonction sera :<br />

unsigned AcqTab(int tb[], unsigned NbMax);<br />

La fonction retourne 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> cette 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. Le<br />

prototype <strong>de</strong> cette fonction sera :<br />

void inittab(int tab[], unsigned nbval);<br />

IV. Écrire une fonction trouvant le minimum et le maximum dans un tableau. Le prototype <strong>de</strong> cette 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 }<br />

-32-


LICENCE SPI-EEA TRAVAUX DIRIGÉS M. <strong>Deloizy</strong><br />

TD4 : CONVERSIONS ASCII / NUMÉRIQUES<br />

I. Écrire une fonction retournant un entier correspondant à la valeur numérique contenue dans une chaîne transmise en<br />

paramètre. Le prototype <strong>de</strong> cette fonction sera :<br />

int AscToInt(const char *<strong>de</strong>cstr);<br />

Cette 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 />

On rappelle qu'un nombre abc peut s'écrire : a<br />

10<br />

<br />

b10<br />

c<br />

II. Écrire une fonction équivalente à la précé<strong>de</strong>nte permettant <strong>de</strong> convertir un nombre écrit en binaire, dont le prototype<br />

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> cette fonction 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> cette<br />

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 et majuscules.<br />

III. Écrire une fonction permettant <strong>de</strong> comparer <strong>de</strong>ux chaînes <strong>de</strong> caractères. Le prototype <strong>de</strong> cette fonction sera :<br />

int cmpstr(const char *str1, const char *str2);<br />

L'entier retourné sera positif si str2 est situé après str1 dans un classement alphabétique et 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> cette fonction sera :<br />

int nbmots(const char *str);<br />

Par exemple, si str contient " le petit train passe dans l'alpage…\n " la fonction doit retourner la valeur 7.<br />

TD6 : FICHIERS<br />

I. Écrire un programme affichant à l'écran les fichiers textes dont les noms seront transmis sur la ligne <strong>de</strong> comman<strong>de</strong><br />

lors <strong>de</strong> l'appel du programme.<br />

II. Écrire un programme affichant le contenu d'un fichier quelconque en hexadécimal et 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 dans<br />

le fichier.<br />

-33-


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

TP1 : DÉCLARATIONS, PREMIERS PROGRAMMES, DÉBOGAGE<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


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

TP2 : MANIPULATIONS DE CHAÎNES DE CARACTÈRES<br />

I. Saisie <strong>de</strong> chaînes<br />

Définir un tableau <strong>de</strong> 80 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 gets<br />

la fonction fgets<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 octets 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 "nettoie" une chaîne saisie par fgets (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> voyelles contenues dans une chaîne (sans distinction <strong>de</strong>s minuscules<br />

et majuscules).<br />

II.2. Écrire une fonction qui renverse une chaîne ("Toto" <strong>de</strong>vient "otoT").<br />

II.3. Écrire une fonction qui duplique chaque caractère d'une chaîne ("Toto" <strong>de</strong>vient "TToottoo").<br />

II.4. Écrire une fonction qui compte le nombre <strong>de</strong> mots contenus dans une chaîne.<br />

-35-


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

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 permettant <strong>de</strong> saisir au clavier les nb premiers éléments du tableau (0 nb < 40).<br />

Le prototype <strong>de</strong> cette 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 mettant nbl valeurs par ligne.<br />

Le prototype <strong>de</strong> cette 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 dans<br />

stdlib.h. Afficher les résultats obtenus.<br />

Exécuter plusieurs fois le programme. Conclure.<br />

II.2. 2 Initialiser le générateur <strong>de</strong> nombres aléatoires en utilisant la fonction srand() (voir prototype). L'initialisation sera<br />

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, et comprises entre 1 et 49.<br />

Le prototype <strong>de</strong> cette fonction sera :<br />

unsigned *Loto(void);<br />

Cette fonction retourne 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.<br />

Classer en ordre croissant ce tableau en utilisant l'algorithme <strong>de</strong> votre choix.<br />

III.2. 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 />

2 Exercice optionnel<br />

-36-


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

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 et affiche son contenu.<br />

Le programme affichera finalement le nombre <strong>de</strong> lignes et <strong>de</strong> caractères composant le fichier.<br />

II. Écriture d'un fichier texte<br />

Écrire un programme qui <strong>de</strong>man<strong>de</strong> à l'utilisateur son nom, prénom, poids, age et sexe (cf. TP1) et sauvergar<strong>de</strong> ces<br />

informations sur le disque dans un fichier texte.<br />

Le nom du fichier sera composé du nom <strong>de</strong> l'individu, suivi d'un nombre <strong>de</strong> 3 chiffres. Ce nombre est incrémenté<br />

automatiquement si nécessaire, afin <strong>de</strong> ne pas effacer un fichier éventuellement existant :<br />

Par exemple, pour Dupont, lors <strong>de</strong> la 1 ère sauvegar<strong>de</strong> on écrit dans "Dupont000.dat".<br />

Lors <strong>de</strong> la 2 ème sauvegar<strong>de</strong>, le fichier créé serait : "Dupont001.dat", etc …<br />

III. Lecture / Écriture d'un fichier texte<br />

Écrire un programme qui lit un fichier texte, renverse les lignes et écrit le résultat dans un nouveau fichier.<br />

Si le fichier à lire contient à l'origine :<br />

Bonjour<br />

Il fait beau<br />

On doit obtenir dans le nouveau fichier :<br />

ruojnoB<br />

uaeb tiaf lI<br />

-37-


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

TP5 : STRUCTURES<br />

I. Définition d'une structure<br />

Définir la structure T_Quot <strong>de</strong> la manière suivante :<br />

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

int num ;<br />

int <strong>de</strong>n ;<br />

} T_Quot ;<br />

Cette structure permet <strong>de</strong> manipuler <strong>de</strong>s nombres rationnels en indiquant par la valeur du numérateur et la valeur du<br />

dénominateur.<br />

II. Encombrement mémoire<br />

Observer (avec l'opérateur sizeof) l'encombrement mémoire <strong>de</strong> cette structure.<br />

III. Tableau <strong>de</strong> structures<br />

Définir un tableau permettant <strong>de</strong> mémoriser 1000 structures, en initialisant les <strong>de</strong>ux premières structures avec les<br />

valeurs 16/9 et 4/3.<br />

Indiquer l'encombrement mémoire <strong>de</strong> ce tableau.<br />

IV. Acquisition et affichage <strong>de</strong>s champs<br />

Écrire une fonction permettant d'acquérir au clavier une structure T_Quot.<br />

Cette fonction posera les questions suivantes :<br />

Entrer le numérateur :<br />

Entrer le dénominateur :<br />

Le prototype <strong>de</strong> cette fonction sera :<br />

void AcqQuot(T_Quot *q);<br />

Écrire une fonction qui affiche la valeur <strong>de</strong> la structure sous la forme : nnn / ddd (Ex : 16/9)<br />

Le prototype <strong>de</strong> cette fonction sera :<br />

void AffQuot(T_Quot *q);<br />

Écrire une fonction qui affiche la valeur numérique <strong>de</strong> la structure sous la forme : xxx.xxx (Ex. : 1.778)<br />

Le prototype <strong>de</strong> cette fonction sera :<br />

void AffValQuot(T_Quot *q);<br />

V. Fonctions <strong>de</strong> manipulation associées :<br />

Écrire les fonctions suivantes :<br />

Multiplication <strong>de</strong> 2 rationnels :<br />

T_Quot *MulQuot(T_Quot *q1, T_Quot *q2) ;<br />

Multiplie (*q1) et (*q2). Range le résultat dans une mémoire interne à la fonction dont lřadresse est renvoyée.<br />

Addition <strong>de</strong> 2 rationnels :<br />

T_Quot *AddQuot(T_Quot *q1, T_Quot *q2) ;<br />

Ajoute (*q1) et (*q2). Range le résultat dans une mémoire interne à la fonction dont lřadresse est renvoyée.<br />

<br />

3 Simplification <strong>de</strong> rationnels :<br />

void SimplQuot(T_Quot *q) ;<br />

Simplifie la fraction contenue dans (*q). Range le résultat dans (*q).<br />

On utilisera un algorithme <strong>de</strong> recherche du pgcd :<br />

Algorithme d’Eucli<strong>de</strong><br />

ENTREE : Deux entiers a et b. - SORTIE : Leur plus grand diviseur commun, pgcd(a,b).<br />

1. Faire tant que le reste est non nul :<br />

Division entière avec reste <strong>de</strong> a et b : a = q · b + r<br />

a ← b; b ← r<br />

2. Retourner b, qui est alors le plus grand diviseur commun.<br />

Exemple : Calcul du pgdc <strong>de</strong> 2926 et 30030. On obtient le tableau suivant.<br />

a b q r<br />

2926 30030 0 2926<br />

30030 2926 10 770<br />

2926 770 3 616<br />

770 616 1 154<br />

616 154 4 0<br />

Le resultat est donc : pgdc(30030, 2926) = 154.<br />

3 Exercice optionnel<br />

-38-


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

TP6 : ÉTUDE DE FONCTIONS MATHÉMATIQUES<br />

I. Définition <strong>de</strong> fonctions mathématiques<br />

Écrire les fonctions (informatiques) permettant <strong>de</strong> calculer les fonctions mathématiques suivantes :<br />

f ( x)<br />

<br />

1<br />

10<br />

<br />

i0<br />

<br />

sin (2 i<br />

1)<br />

x<br />

2 i<br />

1<br />

<br />

sin( x)<br />

f<br />

2<br />

( x)<br />

f3(<br />

x)<br />

sin(10<br />

x)<br />

exp(<br />

x)<br />

x<br />

Constituer un tableau <strong>de</strong> pointeurs <strong>de</strong> fonctions, permettant d'accé<strong>de</strong>r par la suite aux fonctions préalablement 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 permettant <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 et maximale <strong>de</strong> la fonction. Ces informations seront affichées<br />

à 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. Cette fonction permet 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 Point<br />

Exception).<br />

IV. Écriture <strong>de</strong>s résultats dans un fichier<br />

Écrire une fonction permettant <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 et <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) et ceci permettra ainsi <strong>de</strong><br />

manière simple <strong>de</strong> réaliser le tracé <strong>de</strong> la fonction 4 .<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 permettant <strong>de</strong> mettre fin au programme (utiliser la<br />

fonction exit()), en affichant un message d'erreur explicite.<br />

Cette fonction aura le prototype suivant (et utilisera vprintf()) :<br />

void ErrPrintf(const char *format, ...);<br />

On pourra ainsi appeler cette 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 />

etc.…<br />

4 Exercice facultatif.<br />

-39-


LICENCE SPI-EEA TRAVAUX PRATIQUES M. <strong>Deloizy</strong><br />

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 et l'instant <strong>de</strong> la plus forte pente<br />

II. Filtre numérique.<br />

On met 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 />

N<br />

U<br />

filtre<br />

Y<br />

Déterminer expérimentalement la nature du filtre.<br />

La fréquence d'échantillonnage est égale à 1 kHz.<br />

Quels sont le gain et la fréquence <strong>de</strong> coupure pour N = 1 et N = 16<br />

-40-


LICENCE SPI-EEA TABLES DE CODAGE DES CARACTÈRES M. <strong>Deloizy</strong><br />

ASCII :<br />

EBCDIC :<br />

Windows-1252 (CP1252)<br />

x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF<br />

0x NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI<br />

1x DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US<br />

2x SP ! " # $ % & ' ( ) * + , - . /<br />

3x 0 1 2 3 4 5 6 7 8 9 : ; < = > <br />

4x @ A B C D E F G H I J K L M N O<br />

5x P Q R S T U V W X Y Z [ \ ] ^ _<br />

6x ` a b c d e f g h i j k l m n o<br />

7x p q r s t u v w x y z { | } ~ DEL<br />

8x € ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ Ţ<br />

9x Ř ř Ŗ ŗ • Ŕ ŕ ˜ š › œ ţ Ÿ<br />

Ax NBSP ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯<br />

Bx ° ± ² ³ ´ µ · ¸ ¹ º » ¼ ½ ¾ ¿<br />

Cx À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï<br />

Dx Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß<br />

Ex à á â ã ä å æ ç è é ê ë ì í î ï<br />

Fx ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ<br />

-41-


LICENCE SPI-EEA PROTOTYPES (CSTDLIB) M. <strong>Deloizy</strong><br />

<br />

void assert(int expression);<br />

<br />

int isalnum(int c);<br />

int isalpha(int c);<br />

int iscntrl(int c);<br />

int isdigit(int c);<br />

int isgraph(int c);<br />

int islower(int c);<br />

int isprint(int c);<br />

int ispunct(int c);<br />

int isspace(int c);<br />

int isupper(int c);<br />

int isxdigit(int c);<br />

int tolower(int c);<br />

int toupper(int c);<br />

<br />

errno<br />

EDOM<br />

ERANGE<br />

<br />

FLT_RADIX<br />

FLT_ROUNDS<br />

FLT_DIG<br />

DBL_DIG<br />

LDBL_DIG<br />

FLT_EPSILON<br />

DBL_EPSILON<br />

LDBL_EPSILON<br />

FLT_MANT_DIG<br />

DBL_MANT_DIG<br />

LDBL_MANT_DIG<br />

FLT_MAX<br />

DBL_MAX<br />

LDBL_MAX<br />

FLT_MAX_EXP<br />

DBL_MAX_EXP<br />

LDBL_MAX_EXP<br />

FLT_MIN<br />

DBL_MIN<br />

LDBL_MIN<br />

FLT_MIN_EXP<br />

DBL_MIN_EXP<br />

LDBL_MIN_EXP<br />

BIBLIOTHÈQUES (CSTDLIB)<br />

<br />

CHAR_BIT<br />

CHAR_MAX<br />

CHAR_MIN<br />

SCHAR_MAX<br />

SCHAR_MIN<br />

UCHAR_MAX<br />

SHRT_MAX<br />

SHRT_MIN<br />

USHRT_MAX<br />

INT_MAX<br />

INT_MIN<br />

-42-


LICENCE SPI-EEA PROTOTYPES (CSTDLIB) M. <strong>Deloizy</strong><br />

UINT_MAX<br />

LONG_MAX<br />

LONG_MIN<br />

ULONG_MAX<br />

<br />

struct lconv<br />

struct lconv* localeconv(void);<br />

char* setlocale(int category, const char* locale);<br />

LC_ALL<br />

LC_NUMERIC<br />

LC_MONETARY<br />

LC_COLLATE<br />

LC_CTYPE<br />

LC_TIME<br />

NULL<br />

<br />

HUGE_VAL<br />

double exp(double x);<br />

double log(double x);<br />

double log10(double x);<br />

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

double sqrt(double x);<br />

double ceil(double x);<br />

double floor(double x);<br />

double fabs(double x);<br />

double l<strong>de</strong>xp(double x, int n);<br />

double frexp(double x, int* exp);<br />

double modf(double x, double* ip);<br />

double fmod(double x, double y);<br />

double sin(double x);<br />

double cos(double x);<br />

double tan(double x);<br />

double asin(double x);<br />

double acos(double x);<br />

double atan(double x);<br />

double atan2(double y, double x);<br />

double sinh(double x);<br />

double cosh(double x);<br />

double tanh(double x);<br />

<br />

jmp_buf<br />

int setjmp(jmp_buf env);<br />

void longjmp(jmp_buf env, int val);<br />

<br />

SIGABRT<br />

SIGFPE<br />

SIGILL<br />

SIGINT<br />

SIGSEGV<br />

SIGTERM<br />

SIG_DFL<br />

SIG_ERR<br />

SIG_IGN<br />

void (*signal(int sig, void (*handler)(int)))(int);<br />

int raise(int sig);<br />

-43-


LICENCE SPI-EEA PROTOTYPES (CSTDLIB) M. <strong>Deloizy</strong><br />

<br />

va_list<br />

void va_start(va_list ap, lastarg);<br />

type va_arg(va_list ap, type);<br />

void va_end(va_list ap);<br />

<br />

NULL<br />

offsetof(stype, m)<br />

ptrdiff_t<br />

size_t<br />

<br />

BUFSIZ<br />

EOF<br />

FILENAME_MAX<br />

FOPEN_MAX<br />

L_tmpnam<br />

NULL<br />

SEEK_CUR<br />

SEEK_END<br />

SEEK_SET<br />

TMP_MAX<br />

_IOFBF<br />

_IOLBF<br />

_IONBF<br />

stdin<br />

stdout<br />

st<strong>de</strong>rr<br />

FILE<br />

fpos_t<br />

size_t<br />

FILE* fopen(const char* filename, const char* mo<strong>de</strong>);<br />

FILE* freopen(const char* filename, const char* mo<strong>de</strong>, FILE* stream);<br />

int fflush(FILE* stream);<br />

int fclose(FILE* stream);<br />

int remove(const char* filename);<br />

int rename(const char* oldname, const char* newname);<br />

FILE* tmpfile();<br />

char* tmpnam(char s[L_tmpnam]);<br />

int setvbuf(FILE* stream, char* buf, int mo<strong>de</strong>, size_t size);<br />

void setbuf(FILE* stream, char* buf);<br />

int fprintf(FILE* stream, const char* format, ...);<br />

int printf(const char* format, ...);<br />

int sprintf(char* s, const char* format, ...);<br />

int vfprintf(FILE* stream, const char* format, va_list arg);<br />

int vprintf(const char* format, va_list arg);<br />

int vsprintf(char* s, const char* format, va_list arg);<br />

int fscanf(FILE* stream, const char* format, ...);<br />

int scanf(const char* format, ...);<br />

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

int fgetc(FILE* stream);<br />

char* fgets(char* s, int n, FILE* stream);<br />

int fputc(int c, FILE* stream);<br />

char* fputs(const char* s, FILE* stream);<br />

int getc(FILE* stream);<br />

int getchar(void);<br />

char* gets(char* s);<br />

int putc(int c, FILE* stream);<br />

int putchar(int c);<br />

int puts(const char* s);<br />

int ungetc(int c, FILE* stream);<br />

size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream);<br />

-44-


LICENCE SPI-EEA PROTOTYPES (CSTDLIB) M. <strong>Deloizy</strong><br />

size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream);<br />

int fseek(FILE* stream, long offset, int origin);<br />

long ftell(FILE* stream);<br />

void rewind(FILE* stream);<br />

int fgetpos(FILE* stream, fpos_t* ptr);<br />

int fsetpos(FILE* stream, const fpos_t* ptr);<br />

void clearerr(FILE* stream);<br />

int feof(FILE* stream);<br />

int ferror(FILE* stream);<br />

void perror(const char* s);<br />

<br />

EXIT_FAILURE<br />

EXIT_SUCCESS<br />

RAND_MAX<br />

NULL<br />

div_t<br />

ldiv_t<br />

size_t<br />

int abs(int n);<br />

long labs(long n);<br />

div_t div(int num, int <strong>de</strong>nom);<br />

ldiv_t ldiv(long num, long <strong>de</strong>nom);<br />

double atof(const char* s);<br />

int atoi(const char* s);<br />

long atol(const char* s);<br />

double strtod(const char* s, char** endp);<br />

long strtol(const char* s, char** endp, int base);<br />

unsigned long strtoul(const char* s, char** endp, int base);<br />

void* calloc(size_t nobj, size_t size);<br />

void* malloc(size_t size);<br />

void* realloc(void* p, size_t size);<br />

void free(void* p);<br />

void abort();<br />

void exit(int status);<br />

int atexit(void (*fcm)(void));<br />

int system(const char* s);<br />

char* getenv(const char* name);<br />

void* bsearch(const void* key, const void* base, size_t n, size_t size, int<br />

(*cmp)(const void* keyval, const void* datum));<br />

void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const<br />

void*));<br />

int rand(void);<br />

void srand(unsigned int seed);<br />

<br />

NULL<br />

size_t<br />

char* strcpy(char* s, const char* ct);<br />

char* strncpy(char* s, const char* ct, size_t n);<br />

char* strcat(char* s, const char* ct);<br />

char* strncat(char* s, const char* ct, size_t n);<br />

int strcmp(const char* cs, const char* ct);<br />

int strncmp(const char* cs, const char* ct, size_t n);<br />

int strcoll(const char* cs, const char* ct);<br />

char* strchr(const char* cs, int c);<br />

char* strrchr(const char* cs, int c);<br />

size_t strspn(const char* cs, const char* ct);<br />

size_t strcspn(const char* cs, const char* ct);<br />

char* strpbrk(const char* cs, const char* ct);<br />

char* strstr(const char* cs, const char* ct);<br />

size_t strlen(const char* cs);<br />

char* strerror(int n);<br />

char* strtok(char* s, const char* t);<br />

-45-


LICENCE SPI-EEA PROTOTYPES (CSTDLIB) M. <strong>Deloizy</strong><br />

size_t strxfrm(char* s, const char* ct, size_t n);<br />

void* memcpy(void* s, const void* ct, size_t n);<br />

void* memmove(void* s, const void* ct, size_t n);<br />

int memcmp(const void* cs, const void* ct, size_t n);<br />

void* memchr(const void* cs, int c, size_t n);<br />

void* memset(void* s, int c, size_t n);<br />

<br />

CLOCKS_PER_SEC<br />

NULL<br />

clock_t<br />

time_t<br />

struct tm<br />

clock_t clock(void);<br />

time_t time(time_t* tp);<br />

double difftime(time_t time2, time_t time1);<br />

time_t mktime(struct tm* tp);<br />

char* asctime(const struct tm* tp);<br />

char* ctime(const time_t* tp);<br />

struct tm* gmtime(const time_t* tp);<br />

struct tm* localtime(const time_t* tp);<br />

size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp);<br />

-46-


LICENCE SPI-EEA MÉMENTO M. <strong>Deloizy</strong><br />

MÉMENTO DU LANGAGE C<br />

D’après : http://www.inln.cnrs.fr/IMG/pdf/memento-2.pdf<br />

Structure <strong>de</strong> base<br />

#inclu<strong>de</strong> <br />

#inclu<strong>de</strong> <br />

int main()<br />

{<br />

// Programme...<br />

return 0 ;<br />

}<br />

inclusion <strong>de</strong>s en-têtes <strong>de</strong> librairie<br />

début <strong>de</strong> la fonction principale<br />

retour <strong>de</strong> la fonction principale système dřexploitation<br />

Variables et constantes<br />

int i=165;<br />

Nombre entier<br />

long j=8219829; short k=1; Nombres entiers long et courts<br />

char c=’z’;<br />

Caractère (1 octet en général).<br />

float x=3.162e0 ;<br />

Flottant codé souvent sur 4 octets (32 bits)<br />

double y=3.1415926535e0 ; Flottant codé souvent sur 8 octets<br />

double tab[10] ; Tableau <strong>de</strong> dix double. Indices 0 à 9.<br />

char nom[30] = "fichier" ; Chaîne <strong>de</strong> caractères (tableau <strong>de</strong> char)<br />

const int N=10 ;<br />

Constante<br />

#<strong>de</strong>fine N 10<br />

ŖConstanteŗ (en fait substitution)<br />

Entrées et sorties<br />

Entrées/sorties standards :<br />

float x;<br />

scanf("%f", &x); lecture <strong>de</strong> x au clavier<br />

printf("Le resultat est : %f \n", x); écriture <strong>de</strong> x à lřécran<br />

Les indicatifs suivants sont utilisés pour les différents types <strong>de</strong> données.<br />

%f float %lf double %s char[], chaîne<br />

%d int %c char %x entier en hexadécimal, adresse<br />

On peut également entrer %15.10lf pour avoir un double affiché sur 15 cases avec 10 chiffres après la virgule.<br />

Fichiers :<br />

FILE *masortie, *monentree ;<br />

pointeurs sur <strong>de</strong>s fichiers<br />

monentree = fopen("entree.txt","r") ; ouverture en lecture du fichier entree.txt<br />

masortie = fopen("sortie.txt","w") ; ouverture en écriture du fichier sortie.txt<br />

fscanf(monentree,"%f",&x);<br />

lecture <strong>de</strong> la variable x dans le fichier entree.txt<br />

fprintf(masortie,"%f\n",x);<br />

écriture dans le fichier sortie.txt<br />

close(monentree) ; close(masortie) ; fermeture <strong>de</strong>s fichiers<br />

Tests, choix, boucles<br />

La structure <strong>de</strong> contrôle if-else if-else<br />

if (x == y && a != b )<br />

{ à faire si x = y ET a b<br />

}<br />

else if (x > y || a y OU a ≤ b<br />

}<br />

else<br />

{ à faire si les <strong>de</strong>ux premières propositions sont fausses<br />

}<br />

-47-


LICENCE SPI-EEA MÉMENTO M. <strong>Deloizy</strong><br />

La boucle for<br />

for(i=0;i 0.001)<br />

{ action à répéter tant que > 10 −3<br />

}<br />

La boucle do-while<br />

do<br />

{ action à répéter tant que > 10 −3<br />

} while(Delta > 0.001) ;<br />

Dans la boucle while, le test sřeffectue une première fois avant <strong>de</strong> commencer la boucle. Dans la boucle do-while, le<br />

test sřeffectue après la boucle et la boucle sera donc faite au moins une fois.<br />

Fonctions<br />

Fonction retournant une valeur<br />

int f1(float x, char c) fonction prenant un flottant et un char et retournant un entier<br />

{ texte <strong>de</strong> la fonction<br />

· · ·<br />

return 1 ; retourne un entier à la fin<br />

}<br />

Fonction ne retournant rien<br />

Une fonction <strong>de</strong> type void ne retourne pas <strong>de</strong> valeur.<br />

void f2(float x[]) fonction prenant un tableau <strong>de</strong> flottants et ne retournant rien<br />

{ texte <strong>de</strong> la fonction<br />

pas <strong>de</strong> retour à la fin ou return seul. (return ;)<br />

}<br />

Déclaration d’une fonction et utilisation<br />

On déclare une fonction pour lřutiliser dans une autre :<br />

int f1(float, char) ;<br />

void f2(float[]) ;<br />

On lřutilise avec <strong>de</strong>s variables ou <strong>de</strong>s constantes comme paramètres :<br />

i = f1(y,c);<br />

j = f1(10.0,’y’);<br />

f2(tab) ;<br />

Pointeurs et allocation <strong>de</strong> mémoire<br />

Pointeurs<br />

float *pf ; un pointeur sur float (variable contenant une adresse mémoire)<br />

float x=3 ; un float égal à 3<br />

pf = &x ; le pointeur <strong>de</strong>vient égal à lřadresse <strong>de</strong> x<br />

*pf = 4 ; la valeur stockée à cette adresse est modifiée<br />

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

On peut réserver <strong>de</strong> lřespace en mémoire après le démarrage du programme grâce à la fonction malloc qui retourne un<br />

pointeur sans type particulier.<br />

pf = (float*) malloc(10*sizeof(float));<br />

malloc réserve 10 cases en mémoire pouvant chacune contenir un flottant. Elle renvoie lřadresse <strong>de</strong> la première case<br />

mémoire. On transforme cette adresse en type float*, puis on la stocke dans pf.<br />

On accè<strong>de</strong> au contenu <strong>de</strong> la case mémoire 5 <strong>de</strong> différentes manières<br />

x = pf[5] ; ou bien x = *(pf+5) ;<br />

On libère la mémoire à lřai<strong>de</strong> <strong>de</strong> la comman<strong>de</strong> free<br />

free(pf) ;<br />

-48-


LICENCE SPI-EEA MÉMENTO M. <strong>Deloizy</strong><br />

Pointeur <strong>de</strong> fonction<br />

double (*pfonc)(double) ; Pointeur <strong>de</strong> fonction pouvant pointer vers une fonction qui prend un double en<br />

paramètre et retourne un double.<br />

pfonc = cos ; Le pointeur pointe sur cosinus<br />

x = pfonc(3.14) ; il remplace cosinus<br />

Structures et définition <strong>de</strong> type<br />

On peut définir un type comp (nombres complexes) <strong>de</strong> la manière suivante :<br />

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

{ double re ;<br />

double im;<br />

} comp ;<br />

On lřutilise<br />

comp z1 ;<br />

z1.re = 1.0 ; z1.im = 2.0 ;<br />

En vrac...<br />

On dispose <strong>de</strong>s opérateurs arithmétiques : +, -, *, / et %. Ce <strong>de</strong>rnier donne le reste dans une division entière.<br />

Lřopérateur ^ correspond au OU exclusif (opération bit à bit)<br />

On dispose <strong>de</strong>s raccourcis i++ pour i=i+1, x+=3.5 pour x = x + 3.5 .<br />

De même on a les raccourcis : i--, x*=2, x/=1.5...<br />

Lřopérateur (float) convertit en flottant, (int) en entier...<br />

Des constantes mathématiques sont définies avec une gran<strong>de</strong> précision dans math.h. Notamment π sous le nom<br />

<strong>de</strong> M_PI.<br />

-49-


LICENCE SPI-EEA TABLE DES MATIÈRES M. <strong>Deloizy</strong><br />

Table <strong>de</strong>s Matières<br />

Introduction .................................................................................................................................................................. 2<br />

Description du langage ................................................................................................................................................. 2<br />

I. Constitution dřun programme C ......................................................................................................................... 2<br />

I.1. Généralités .................................................................................................................................................. 2<br />

I.2. Syntaxe ....................................................................................................................................................... 2<br />

I.2.a. Commentaires. ................................................................................................................................. 2<br />

I.2.b. Noms <strong>de</strong> symboles. .......................................................................................................................... 2<br />

I.2.c. Minuscules et majuscules. ............................................................................................................... 2<br />

I.3. Mots clés ..................................................................................................................................................... 3<br />

II. Types <strong>de</strong> variables ............................................................................................................................................. 3<br />

II.1. Les types <strong>de</strong> base ....................................................................................................................................... 3<br />

II.1.a. char : ................................................................................................................................................ 3<br />

II.1.b. int : .................................................................................................................................................. 3<br />

II.1.c. float : ............................................................................................................................................... 3<br />

II.2. Les types dérivés ....................................................................................................................................... 3<br />

II.2.a. unsigned char : ................................................................................................................................ 3<br />

II.2.b. signed char : .................................................................................................................................... 3<br />

II.2.c. unsigned int ou unsigned : ............................................................................................................... 3<br />

II.2.d. short : .............................................................................................................................................. 3<br />

II.2.e. unsigned short : ............................................................................................................................... 3<br />

II.2.f. long int ou long : .............................................................................................................................. 3<br />

II.2.g. unsigned long int ou unsigned long : .............................................................................................. 3<br />

II.2.h. double : ........................................................................................................................................... 3<br />

II.2.i. long double : .................................................................................................................................... 4<br />

II.2.j. Dynamique <strong>de</strong>s nombres : ................................................................................................................ 4<br />

II.3. Les types composés ................................................................................................................................... 4<br />

II.3.a. les tableaux : .................................................................................................................................... 4<br />

II.3.b. les structures : ................................................................................................................................. 4<br />

II.3.c. les unions : ...................................................................................................................................... 5<br />

II.4. Autres types ............................................................................................................................................... 5<br />

II.4.a. les types définis par le programmeur .............................................................................................. 5<br />

II.4.b. void ................................................................................................................................................. 5<br />

III. La déclaration <strong>de</strong>s variables ............................................................................................................................. 5<br />

IV. Constantes ....................................................................................................................................................... 5<br />

V. Organisation générale d'un module ................................................................................................................... 7<br />

VI. Constitution d'une fonction ............................................................................................................................. 7<br />

VI.1. Définition d'une fonction ......................................................................................................................... 7<br />

VI.2. Prototypes ................................................................................................................................................ 8<br />

VII. Blocs d'instructions ........................................................................................................................................ 8<br />

VII.1. Opérateurs ............................................................................................................................................... 9<br />

VII.1.a. Opérateurs arithmétiques :............................................................................................................ 9<br />

VII.1.b. Opérateurs logiques : ................................................................................................................... 9<br />

VII.1.c. Opérateurs d'affectation : ............................................................................................................. 9<br />

VII.1.d. Opérateur ternaire : .................................................................................................................... 10<br />

VII.1.e. Séquenceur : ............................................................................................................................... 10<br />

VII.1.f. Opérateurs unaires : .................................................................................................................... 10<br />

VII.2. Expressions ........................................................................................................................................... 11<br />

VII.3. Instructions <strong>de</strong> contrôle <strong>de</strong> déroulement ............................................................................................... 11<br />

VII.3.a. Tests si … sinon … ..................................................................................................................... 11<br />

VII.3.b. Boucles tant que … faire : .......................................................................................................... 11<br />

VII.3.c. Boucles faire … tant que : .......................................................................................................... 12<br />

VII.3.d. Boucles for .............................................................................................................................. 12<br />

VII.3.e. Tests énumératifs (switch … case) ............................................................................................. 12<br />

VII.3.f. Rupture <strong>de</strong> séquence break : .................................................................................................... 13<br />

VII.3.g. Rupture <strong>de</strong> séquence continue : ............................................................................................ 13<br />

VII.3.h. Branchements inconditionnels ................................................................................................... 13<br />

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

VIII.1. Donnée globale au programme ............................................................................................................ 14<br />

VIII.2. Donnée locale à un module ................................................................................................................. 14<br />

VIII.3. Donnée locale à une fonction .............................................................................................................. 14<br />

-50-


LICENCE SPI-EEA TABLE DES MATIÈRES M. <strong>Deloizy</strong><br />

VIII.4. Donnée locale à un bloc d'instructions ................................................................................................ 14<br />

IX. Classes d'allocation........................................................................................................................................ 14<br />

IX.1. static ....................................................................................................................................................... 15<br />

IX.2. auto ......................................................................................................................................................... 15<br />

IX.3. const ....................................................................................................................................................... 15<br />

IX.4. register.................................................................................................................................................... 15<br />

IX.5. volatile.................................................................................................................................................... 15<br />

X. Les pointeurs ................................................................................................................................................... 16<br />

X.1. Définition ................................................................................................................................................ 16<br />

X.2. Arithmétique <strong>de</strong>s pointeurs...................................................................................................................... 16<br />

X.3. Utilité <strong>de</strong>s pointeurs ................................................................................................................................. 17<br />

X.3.a. Les tableaux ..................................................................................................................................... 17<br />

X.3.b. Chaînes <strong>de</strong> caractères ....................................................................................................................... 17<br />

X.3.c. Fonctions et pointeurs ...................................................................................................................... 17<br />

XI. Les fichiers .................................................................................................................................................... 18<br />

XI.1. Notion <strong>de</strong> flux ........................................................................................................................................ 18<br />

XI.2. Flux en sortie. ......................................................................................................................................... 19<br />

XI.3. Flux en entrée. ........................................................................................................................................ 19<br />

XI.4. Fonctions <strong>de</strong> gestion ............................................................................................................................... 19<br />

XII. Fonctions standard ....................................................................................................................................... 19<br />

XII.1. Manipulation <strong>de</strong> chaînes <strong>de</strong> caractères ............................................................................... 19<br />

XII.1.a. Traitement <strong>de</strong> données brutes ..................................................................................................... 20<br />

XII.1.b. Copie et concaténation : ............................................................................................................. 20<br />

XII.1.c. Comparaisons <strong>de</strong> chaînes <strong>de</strong> caractères : .................................................................................... 20<br />

XII.1.d. Recherche <strong>de</strong> séquences : ........................................................................................................... 21<br />

XII.1.e. Fonctions diverses : .................................................................................................................... 21<br />

XII.2. Entrées sorties ...................................................................................................................... 22<br />

XII.2.a. Entrées / Sorties formatées : ....................................................................................................... 22<br />

XII.2.b. Spécifications <strong>de</strong> format (pour printf et scanf) : ......................................................................... 22<br />

XII.2.c. Fonctions d'entrées : ................................................................................................................... 23<br />

XII.2.d. Fonctions <strong>de</strong> sorties : .................................................................................................................. 23<br />

XII.2.e. Gestion <strong>de</strong> fichiers (flux) :.......................................................................................................... 24<br />

XII.2.f. Exemple : copie <strong>de</strong> fichier texte ................................................................................................. 25<br />

XII.3. Fonctions utilitaires : ........................................................................................................... 25<br />

XII.3.a. Conversion <strong>de</strong> chaînes <strong>de</strong> caractères : ........................................................................................ 25<br />

XII.3.b. Générateur <strong>de</strong> nombres aléatoires : ............................................................................................ 26<br />

XII.3.c. Fouilles et tris : ........................................................................................................................... 26<br />

XII.3.d. Allocation <strong>de</strong> mémoire : ............................................................................................................. 26<br />

XII.3.e. Fonctions système : .................................................................................................................... 27<br />

XII.3.f. Opérations sur <strong>de</strong>s entiers : ......................................................................................................... 27<br />

XIII. Structures .................................................................................................................................................... 28<br />

XIV. Le préprocesseur ......................................................................................................................................... 29<br />

XIV.1. Comman<strong>de</strong> inclu<strong>de</strong>. ............................................................................................................................. 29<br />

XIV.2. Comman<strong>de</strong> <strong>de</strong>fine. .............................................................................................................................. 29<br />

Constantes : ................................................................................................................................................. 29<br />

Macro-définitions : ..................................................................................................................................... 29<br />

XIV.3. Compilation conditionnelle ................................................................................................................. 30<br />

TD1 : Types <strong>de</strong> données – Codage ............................................................................................................................ 31<br />

TD2 : Premiers programmes ..................................................................................................................................... 32<br />

TD3 : Utilisation <strong>de</strong> tableaux. .................................................................................................................................... 32<br />

TD4 : Conversions ASCII / numériques ................................................................................................................... 33<br />

TD5 : Traitements sur les chaînes ............................................................................................................................. 33<br />

TD6 : Fichiers ............................................................................................................................................................. 33<br />

TP1 : Déclarations, Premiers programmes, Débogage ........................................................................................... 34<br />

TP2 : Manipulations <strong>de</strong> Chaînes <strong>de</strong> Caractères....................................................................................................... 35<br />

TP3 : Tableaux <strong>de</strong> données ........................................................................................................................................ 36<br />

TP4 : Fichiers .............................................................................................................................................................. 37<br />

TP5 : Structures ......................................................................................................................................................... 38<br />

-51-


LICENCE SPI-EEA TABLE DES MATIÈRES M. <strong>Deloizy</strong><br />

TP6 : Étu<strong>de</strong> <strong>de</strong> fonctions mathématiques ................................................................................................................. 39<br />

TP7 : Acquisition et Traitement <strong>de</strong> données ............................................................................................................ 40<br />

Bibliothèques (Cstdlib)............................................................................................................................................... 42<br />

................................................................................................................................................................. 42<br />

................................................................................................................................................................. 42<br />

................................................................................................................................................................. 42<br />

................................................................................................................................................................... 42<br />

................................................................................................................................................................. 42<br />

................................................................................................................................................................ 43<br />

.................................................................................................................................................................. 43<br />

............................................................................................................................................................... 43<br />

................................................................................................................................................................ 43<br />

................................................................................................................................................................ 44<br />

................................................................................................................................................................ 44<br />

.................................................................................................................................................................. 44<br />

................................................................................................................................................................. 45<br />

................................................................................................................................................................. 45<br />

................................................................................................................................................................... 46<br />

Mémento du langage C .............................................................................................................................................. 47<br />

Structure <strong>de</strong> base ...................................................................................................................................................... 47<br />

Variables et constantes ............................................................................................................................................. 47<br />

Entrées et sorties ...................................................................................................................................................... 47<br />

Fichiers : .................................................................................................................................................................. 47<br />

Tests, choix, boucles ................................................................................................................................................ 47<br />

La structure <strong>de</strong> contrôle if-else if-else ................................................................................................................. 47<br />

La boucle for ........................................................................................................................................................ 48<br />

La boucle while ................................................................................................................................................... 48<br />

La boucle do-while .............................................................................................................................................. 48<br />

Fonctions .................................................................................................................................................................. 48<br />

Fonction retournant une valeur ............................................................................................................................ 48<br />

Fonction ne retournant rien .................................................................................................................................. 48<br />

Déclaration dřune fonction et utilisation ............................................................................................................. 48<br />

Pointeurs et allocation <strong>de</strong> mémoire .......................................................................................................................... 48<br />

Pointeurs .............................................................................................................................................................. 48<br />

Allocation <strong>de</strong> mémoire ........................................................................................................................................ 48<br />

Pointeur <strong>de</strong> fonction............................................................................................................................................. 49<br />

Structures et définition <strong>de</strong> type ................................................................................................................................ 49<br />

En vrac... .................................................................................................................................................................. 49<br />

Table <strong>de</strong>s Matières ........................................................................................................................................................... 50<br />

-52-

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!