Sunteți pe pagina 1din 22

Universit Paris-Sud 11

Facult des sciences dOrsay

IFIPS S5
TRONC COMMUN
Anne 2007-2008

C dans la poche
Thomas Rodet
Introduction
Ce polycopi a pour but de prsenter de manire synthtique les bases du langage C, cest--dire de dlivrer
le strict minimum. Pour faire ce polycopi je me suis largement inspir du cours de PATRICK GONORD, de MI-
CHEL DESAINTFUSCIEN et du livre de FRANOISE PERRIN A la decouverte du C++ aux ditions Cpadus
(1996).
1 Rappels
1.1 Structure dun programme en C
Un programme en C est une collection de fonctions. Lune des fonctions doit sappeler main. Lexcution
dun programme C correspond lexcution de la fonction main. Les autres fonctions sont excutes si elles
sont appeles dans la fonction main.
Exemple :
#include<stdio.h> /
*
inclusion dun fichier permettant lutilisation
*
/
/
*
de fonctions dj codes
*
/
int AuCarre(int); /
*
prototypage de notre fonction AuCarre
*
/
int main()
{ /
*
lexcution commence ici
*
/
int resultat; /
*
dclaration de variables locales
*
/
int valeur = 5;
resultat = AuCarre(valeur); /
*
Appel de AuCarre
*
/
printf("resultat = %d \n",resultat); /
*
Appel fonction bibliothque
*
/
}
int AuCarre(int parametre) /
*
code de la fonction AuCarre
*
/
{
return parametre
*
parametre;
}
La structure des programmes crits en C est toujours similaire celle expose dans lexemple ci-dessus.
Tout dabord, on inclut des chiers dentte permettant dutiliser des fonctions bibliothques (fonctions dj
codes). Puis, on crit le prototypage des fonctions que lon dveloppe. Le prototype permet de dcrire la
manire dutiliser la fonction sans spcier comment elle est code. Ensuite, il y a le corps du programme qui
T. Rodet Le 11 juillet 2007
C dans la poche 2
correspond la fonction main. Enn, on crit le code des fonctions dont les prototypes ont t dclars au
dbut du programme.
Remarques : En gnral, le code de chaque fonction est enregistr dans des chiers spars et les prototy-
pages sont enregistrs dans un chier dentte an damliorer la lisibilit des codes.
1.2 Rgles dcriture des programmes C
An dcrire des programmes C lisibles, il est important de respecter un certain nombre de rgles de pr-
sentation :
ne jamais placer plusieurs instructions sur une mme ligne
utiliser des identicateurs (noms des variables, des fonctions) signicatifs
grce lindentation des lignes, on fera ressortir la structure syntaxique du programme
on laissera une ligne blanche entre la dernire ligne des dclarations et la premire ligne des instructions
une accolade fermante est seule sur une ligne et elle est aligne avec laccolade ouvrante du bloc corres-
pondant.
votre programme doit tre modulaire (compos de plusieurs fonctions lmentaires).
limiter le plus possible lutilisation de variables globales.
il est ncessaire de commenter le code en vitant les commentaires triviaux.
1.3 Les variables et leurs portes
En informatique, nous sommes obligs dattribuer un type une valeur. En effet, les diffrentes valeurs
dans le monde qui nous entoure ne sont pas forcment comparables. Par exemple on ne peut pas comparer un
complexe et un entier ou un rel avec un caractre. Cest pourquoi, on associe un type aux valeurs pour dnir
des oprations associes aux valeurs. (voir tableau 1).
Type signication Taille (en octet) plage de valeurs codes
char caractre 1 -128 127
unsigned char caractre 1 0 255
short entier court 2 -32 768 32 767
unsigned short entier court 2 0 65 535
int entier 4 -2 147 483 648 2 147 483 647
unsigned int entier 4 0 4 294 967 295
long entier long 4 -2 147 483 648 2 147 483 647
unsigned long entier long 4 0 4 294 967 295
oat rel simple prcision 4 3.4*10
38
3.4*10
38
double rel double prcision 8 1.7*10
308
1.7*10
308
TAB. 1 Les diffrents types de base en C
Mmoire
Valeur
Adresse
Variable
FIG. 1 Illustration de ladresse dune variable
T. Rodet IFIPS S5
C dans la poche 3
1.3.1 Les variables
Une variable est un conteneur dinformation, physiquement cest un espace dans la mmoire de lordina-
teur. Linformation contenue dans la variable est appele valeur de la variable, elle est modiable. La variable
possde le mme type que linformation quelle contient. Le type dune variable nest pas modiable. Enn, la
variable correspond physiquement une zone mmoire de lordinateur (voir gure 1). Cette zone est repre
par une adresse, et bien sr cette adresse nest pas modiable.
Attention : Le nom dune variable (identicateur) ne peut pas commencer par un chiffre.
Affectation des variables : Lorsque lon rencontre un oprateur gal dans un programme en C, comme
dans lexemple ci-dessous, il sagit dune affectation et non dune galit. En effet, la premire ligne du code
cre deux variables entires i,j et initialise j la valeur 3. Sur la deuxime ligne, les deux variables de chaque
cot de lgalit ne reprsentent pas la mme chose, on parle de left value et de right value. A droite du signe
gal, j reprsente la valeur de j, cest dire 3. A gauche du signe gal, i reprsente une variable, cest dire
un contenant. Exemple :
int i,j=3;
i = j; /
*
copie de la valeur de j dans la variable i
*
/
Attention : si la valeur droite de lgalit nest pas de mme type que la variable gauche de lgalit, la
valeur sera transforme pour correspondre au type de la vari able (transtypage).
Transtypage : Il est parfois utile de changer le type dune valeur. En effet, la division de deux entiers renvoie
un entier (division Euclidienne) par exemple 5 diviser par 2 renvoie 2, car la division euclidienne 5 par 2 est
gale 2.
Comment faire pour obtenir le rsultat avec un nombre rel ? Il faut utiliser la syntaxe suivante : 5./2, dans
ce cas 5. est interprt comme un nombre rel. Le complilateur converti les deux menbres de lopration en
rel et effectu une division de rels. Mais que faire quand on se trouve avec des variables entires ( i et j par
exemple ) ? Il faut changer le type de lune des deux variables. Cette opration sappelle le transtypage. On la
ralise simplement en faisant prcder lexpression transtyper du type dsir entour de parenthses :
<type1> Var1;
<type2> Var2;
Var2= (<type2>) Var1;
Exemple :
int Var1=35;
float Var2;
Var2= ((float) Var1)/ 2;
1.3.2 La porte des variables
Lorsque lon programme, on distingue deux types de variables :
Les variables globales qui sont visibles et modiables dans lensemble du code ( porte innie).
Les variables locales qui ont une porte locale. Gnralement la porte de ces variables est limite la
fonction dans laquelle elles ont t dclares.
T. Rodet IFIPS S5
C dans la poche 4
Exemple :
#include<stdio.h>
float pi=3.1415926535898 /
*
variable globale pi
*
/
float Radian2Degree(float); /
*
prototypage de Radian2Degree
*
/
int main()
{
float resultat; /
*
variables locales resultat et valeur
*
/
float valeur = 1.32;
resultat = Radian2Degree(valeur);
printf("resultat = %d \n",resultat);
} /
*
les variables resultat et valeur sont dtruites
*
/
/
*
Dclaration de la fonction Radian2Degree
*
/
float Radian2Degree(float parametre) /
*
variable locale parametre
*
/
{
return (parametre/pi)
*
180.0;
} /
*
la variable parametre est dtruite
*
/
1.3.3 Les variables constantes
Dans certain cas on a besoin de variables constantes. Ces variables, on ne veut pas quelles puissent tre
modies au cours de lxecution.
Pour dclarer une variable constante on met le mot const devant la dclaration de la variable. Exemple :
const float pi = 3.1415926535898
Une autre faon de dclarer des variables constantes est dutiliser des instructions de prcompilation :
Exemple :
#define PI 3.1415926535898
Par convention ces constantes se notent en capitale.
1.4 Les fonctions (ou sous programmes)
Pourquoi crire des fonctions ?
Pour augmenter la lisibilit du code (cela vite les copier/coller).
Pour faciliter la maintenance du code, cela limite les interdpendances dans le code.
Pour construire des outils gnriques, (lutilisation de ces outils augmente la rapidit de codage).
Rgle de conception dune fonction : Pour tirer prot au maximum du dcoupage du code en fonctions, il
faut respecter les rgles de conception suivantes :
une fonction ne doit pas effectuer dautres traitements que ceux ncessaires au traitement principal
une fonction doit accomplir entirement une seule tche et tous les traitements ncessaires cette tche
doivent tre localiss dans la fonction.
La tche affecte la fonction doit tre dnie avec prcision. Vous devez pouvoir utiliser la fonction
sans avoir connatre les dtails de son criture (Encapsulation).
T. Rodet IFIPS S5
C dans la poche 5
Dnitions des fonctions
<type> NomFonction(<liste de paramtres>)
{
/
*
Dclaration des variables locales
*
/
/
*
Corps de la fonction
*
/
return valeur;
}
<type> est le type de la valeur retourne par la fonction. Si la fonction ne retourne rien le type est void.
En C il y a forcment un type de retour.
La <liste de paramtres>est de la forme : <typeArg1> VariableArg1, <typeArg2>
VariableArg2, . . .. Les VariableArg1, VariableArg2, . . . sont visibles uniquement dans le
corps de la fonction. Si la fonction na pas de paramtre, la liste est vide.
return valeur : renvoie valeur qui doit tre du type de <type>.
Appel des fonctions : On nomme appel dune fonction lutilisation de la fonction. Cet appel peut aussi bien
se faire depuis la fonction main que depuis une autre fonction (on peut mme appeler la fonction dans le corps
de cette dernire, cest ce que lon appelle la programmation rcursive).
...
<type> NomFonction(<typeArg1>,<typeArg2>,...); /
*
prototypage
*
/
int main()
{
<type> UneVariable;
...
UneVariable = NomFonction(parametres1,parametre2,...); /
*
appel
*
/
}
<type> NomFonction(<typeArg1> Arg1,<typeArg2> Arg2,...)) /
*
Dclaration
*
/
{
...
}
Comme le compilateur procde un traitement squentiel du chier source (il traite successivement les
lignes de code de haut en bas), il faut dnir au dbut du chier le prototypage des fonctions que lon va utiliser
dans le code. Ce prototypage rsume lutilisation de la fonction. Le compilateur peut vrier si les paramtres
passs en argument de la fonctions sont cohrents avec son fonctionnement.
Que se passe t-il en mmoire durant lappel dune fonction ?
Nous allons tudier les tapes de lexcution du programme suivant au niveau de la mmoire :
T. Rodet IFIPS S5
C dans la poche 6
1 int AuCarre(int); /
*
prototypage de notre fonction AuCarre
*
/
2
3 int main()
4 {
5 int resultat; /
*
dclaration de variables locales
*
/
6 int argument = 5;
7
8 resultat = AuCarre(argument); /
*
Appel de AuCarre
*
/
9 }
10
11 int AuCarre(int parametre) /
*
code de la fonction AuCarre
*
/
12 {
13 return (parametre
*
parametre);
14 }
Mmoire
argument
5
resultat
?
FIG. 2 tat de la mmoire la ligne 7 de lexcution
Mmoire
5
parametre
resultat
?
argument
5
FIG. 3 tat de la mmoire la ligne 12 (dans la fonction AuCarre), les variables grises ne sont pas visibles
depuis cette ligne
Faisons lexcution pas pas du programme ci-dessus. Lexcution commence la ligne 4. Les lignes 5
et 6 crent deux variables et affectent 5 dans la variable argument (voir gure 2). Lappel de la fonction
AuCarre se fait la ligne 8 en passant comme paramtre la valeur de la variable argument (cest dire 5).
Suite lappel de la fonction, lexcution saute la ligne 11, dans laquelle la variable parametre est cre
et est initialise 5. Notons que dans cette partie du code, les variables argument et resultat ne sont pas
modiables (voir gure 3). Lorsque lexcution de la fonction est nie on retourne la ligne 8 et lon affecte
T. Rodet IFIPS S5
C dans la poche 7
Mmoire
resultat
25
argument
5
5
parametre
FIG. 4 tat de la mmoire la ligne 9
la variable resultat la valeur retourne par la fonction. Enn, lorsque lexcution de la fonction est termine,
toutes les variables dclares dans cette fonction sont dtruites (voir gure 4).
1.5 Les structures de choix
Les structures de choix permettent de prendre une dcision en fonction de certaines conditions.
1.5.1 Choix simple
...
if ( <condition> ) /
*
si la condition est vrifie faire ...
*
/
{
...
}
else /
*
sinon faire ...
*
/
{
...
}

Facultatif
T. Rodet IFIPS S5
C dans la poche 8
1.5.2 Choix multiple
switch( Variable ) /
*
si la condition est vrifie faire ...
*
/
{
case 1 : /
*
Variable == 1 faire
*
/
{
...
break;
}
case 2 : /
*
Variable == 2 faire
*
/
{
...
break;
}
default : /
*
sinon faire
*
/
{
...
break;
}

Facultatif
}
1.6 Rptition de squences (boucles)
Il existe trois instructions permettant de faire des boucles : while, do while et for.
1.6.1 While
Syntaxe : while (<condition>) { <liste dinstructions> }
La rptition de la liste dinstructions se fait tant que la condition est vraie. Au dbut de chaque itration, on
value la condition, et si celle-ci est vraie on excution la liste dinstructions.
Exemple :
int indice; /
*
code calculant la somme des max premiers entiers
*
/
int max=20; int somme = 0;
while ( indice<=max )
{
indice = indice + 1;
somme = somme + indice;
}
1.6.2 Do while
Syntaxe : do { <liste dinstructions> } while (<condition>);
Linstruction do while a un fonctionnement trs proche de linstruction while. Dans le cas du do while
le test de la condition se fait aprs la liste dinstructions, tandis que pour le while le test se fait avant la liste.
T. Rodet IFIPS S5
C dans la poche 9
1.6.3 For
Syntaxe : for ( <initialisation>; <condition>; <incrementation>)
Linstruction for est trs utilise car elle est souvent plus lisible que linstruction while. En effet, elle re-
groupe sur la mme ligne, linitialisation des variables dindices, la condition de rptition de la boucle et la
mise jour de certaines variables.
Exemple :
int indice=0; /
*
code calculant la somme des max premiers entiers
*
/
int max=20;
int somme = 0;
for ( indice=1; indice <= max; indice ++ )
{
somme = somme + indice;
}
Attention : Les sparateurs dans linstruction for sont des points virgules et non des virgules.
2 Les pointeurs
Dnition : Un pointeur est un conteneur qui sert accder directement la mmoire physique de lordina-
teur. Cest une variable qui contient une adresse mmoire.
Dclaration :
<type>
*
nomPtr;
nomPtr : nom du pointeur (identiant).
<type> : type de la variable dont ladresse sera contenue dans le pointeur.
Affectation des pointeurs : Comme pour les variables classiques les pointeurs ne reprsentent pas la mme
chose des deux cots dune quation. Dans lgalit de lexemple ci-dessous ptr2 reprsente un contenant et
ptr1 reprsente une adresse cest--dire ce que contient le pointeur.
Loprateur & : Cet oprateur permet de connatre ladresse dune variable (voir exemple ci dessous).
Loprateur * : Cet oprateur appliqu un pointeur, permet daccder la valeur de la variable pointe (voir
exemple ci dessous).
Exemple :
int
*
ptr1=NULL;
int
*
ptr2=NULL; /
*
dclaration de deux pointeurs sur des entiers
*
/
int i,j; /
*
dclaration de deux variables entires
*
/
ptr1 = &i; /
*
ptr1 contient ladresse de i
*
/
ptr2 = ptr1; /
*
ptr2 contient ladresse contenue dans ptr1
*
/
*
ptr2 = 3; /
*
la variable pointe par ptr2 (i) reoit la valeur 3
*
/
j =
*
ptr1; /
*
affectation de 3 dans j
*
/
Attention : La dclaration du pointeur ne rserve pas la place mmoire de la variable pointe ! ! !
int
*
i=NULL;
*
i =3; /
*
erreur lexcution
*
/
T. Rodet IFIPS S5
C dans la poche 10
ptr
Adresse de var
var
Valeur de var
Adresse de var
Mmoire
Adresse de ptr
ptr pointe sur var
FIG. 5 Reprsentation mmoire
2.1 Utilisation des pointeurs dans le passage de paramtres aux fonctions
Comme nous lavons vu dans la partie 1.4, les fonctions en C ont uniquement un paramtre de retour.
Nous avons vu des fonctions qui ont plusieurs valeurs dentre (les paramtres) et une valeur de sortie (le
paramtre de retour). Lutilisation de pointeurs comme paramtres de fonction permet dintroduire des variables
dentre/sortie la fonction. En effet si nous voulons raliser une fonction qui change le contenu de deux
variables, nous sommes obligs dutiliser des pointeurs comme paramtres car nous avons faire 2 variables
dentre/sortie. Exemple de la fonction Echange :
1 void Echange(int
*
,int
*
); /
*
prototypage de la fonction Echange
*
/
2
3 int main()
4 {
5 int var1=6,var2=-32; /
*
dclaration de variables locales
*
/
6
7 Echange(&var1,&var2); /
*
Appel de Echange
*
/
8 }
9 void Echange(int
*
a, int
*
b)
10 {
11 int tampon;
12 tampon =
*
b;
13
*
b =
*
a;
14
*
a = tampon
15 }
Que se passetil en mmoire durant lappel dune fonction echange?
3 Les tableaux
Dnition : un tableau cest un bloc monolithique de mmoire contenant une collection de variables de
mme type et adjacentes. Le nom du bloc est le nom du tableau. On peut accder individuellement toutes les
composantes du bloc.
3.1 Tableaux mono-dimensionnel
Dclaration :
<type> nomTab[nbElements];
T. Rodet IFIPS S5
C dans la poche 11
Mmoire
var1
6
var2
32
FIG. 6 tat de la mmoire la ligne 6 de lexcution
Mmoire
add var1
a
add var2
b
??
tampon
var2
32
*b
6
var1
*a
FIG. 7 tat de la mmoire la ligne 11 (dans la fonction Echange), les variables grises ne sont pas visibles
depuis cette ligne.
Mmoire
add var1
a
add var2
b
32
tampon
var2
6
*b
32
var1
*a
FIG. 8 tat de la mmoire la ligne 15
Mmoire
add var1
a
add var2
b
32
tampon
var2
6
32
var1
FIG. 9 tat de la mmoire la ligne 8
T. Rodet IFIPS S5
C dans la poche 12
<type> type des lments du tableau.
nomTab nom du tableau.
nbElements nombre dlments du tableau, le compilateur doit connatre sa valeur an de rserver la
place mmoire ncessaire.
Initialisation : Linitialisation dun tableau se fait en mme temps que la dclaration, cest dire avec lex-
cution proprement dit du programme. Linitialisation se fait en donnant entre accolades les valeurs du tableau
spares par des virgules dans lordre o elles seront crites en mmoire.
<type> nomTab[nbElements]=

val
0
,val
1
,...,val
nbElements1

;
Attention : La syntaxe ci-dessus ne sapplique pas en dehors de la dclaration.
Loprateur crochet : On peut accder chaque composante lmentaire dun tableau en donnant le nom
dun tableau suivi entre [] de la valeur de lindice de la composante souhaite.
.
.
.
int tabInt[4]={5,8,2,23};
printf("la valeur de la 4me composante est %d",tabInt[3]);
.
.
.
Ce programme donne lors de son excution :
la valeur de la 4me conposante est 23
Loprateur * : Le nom dun tableau sans crochet est interprt par le compilateur comme un pointeur qui
contient ladresse du premier lment du tableau. On peut donc accder aux valeurs du tableau laide de
loprateur *. Rcrivons le code ci-dessus en utilisant un pointeur.
.
.
.
int tabInt[4]={5,8,2,23};
printf("la valeur de la 4me composante est %d",
*
(tabInt+3));
.
.
.
Ce programme donne lors de son excution :
la valeur de la 4me conposante est 23
Attention : dans lexemple ci-dessus tabInt+3 pointe sur la quatrime case du tableau.
3.2 Chanes de caractres
Une chane de caractres est un tableau de caractres contenant un caractre spcial \0 permettant de
reprer la n de la chane. Par exemple, la reprsentation en mmoire de char chaine[10]="bonjour"
est la suivante :
b o n j o u r \0 ? ? ? ?
Initialisation : Il existe une initialisation des chanes de caractres plus simple que pour les tableaux. norma-
lement on devrait crire :
char chaine[10]={b,o,n,j,o,u,r,\0};
Comme il sagit dune chane de caractres on peut crire plus simplement :
char chaine[10]="bonjour";
T. Rodet IFIPS S5
C dans la poche 13
Ces deux notations sont bien videmment strictement quivalentes.
Attention : il faut dnir un tableau de caractres sufsamment grand pour contenir toute la chane sans
oublier le caractre de n de chane. Il faut donc dnir un tableau de caractres comprenant un nombre de
cases mmoire au moins gal au nombre de caractres + 1.
Les fonctions standards de gestion des chanes de caractres.
int strlen (const char
*
s); /
*
renvoie la longueur de la chaine
*
/
char
*
strcpy (char
*
s1, const char
*
s2); /
*
copie la chaine s2 dans s1
*
/
int strcmp (const char
*
s1, const char
*
s2); /
*
compare deux chaines
*
/
char
*
strcat (char
*
dest, const char
*
src); /
*
concatne deux chaines
*
/
Pour une description plus dtaille utiliser laide en ligne.
Attention : Les chanes de caractres tant des tableaux (pointeur constant) les lignes suivantes provoquent
une erreur :
char chaine1[10]="bonjour";
char chaine2[10];
.
.
.
chaine2 =chaine1; /
*
ERREUR A LA COMPILATION
*
/
Pour copier la premire chane de caractres dans la deuxime il faut utiliser la fonction strcpy:
strcpy(chaine2
4 Allocation dynamique
Lallocation dynamique permet de rserver la place mmoire pour des variables et des tableaux de tous
types au cours de lexcution. Lallocation dynamique est incontournable lorsquon veut programmer avec un
soucis doptimisation de la place mmoire utilise.
La rservation de la place mmoire (allocation) se fait laide de la fonction malloc.
void
*
malloc(int ); /
*
prototypage de la fonction malloc
*
/
La fonction malloc reoit en argument le nombre doctets rserver en mmoire et elle renvoie ladresse
mmoire de la premire case rserve. Cette adresse de retour est transmise de manire gnrique (void
*
).
Il faut changer le type de cette adresse (transtypage) an de la copier dans le pointeur associ au tableau ou
la variable.
Allocation dun tableau, exemple un tableau de 10 entiers :
int n=10;
int
*
tabInt;
tabInt = (int
*
) malloc(sizeof(int)
*
n);
Nous voyons dans lexemple ci-dessus quon utilise linstruction sizeof(<type>) pour calculer le
nombre doctets dun certain type de donnes. De plus, nous devons modier le type de ladresse revoye par
la fonction, void
*
(adresse gnrique), pour la copier dans le pointeur qui possde un type donn.
T. Rodet IFIPS S5
C dans la poche 14
Allocation de la variable associe un pointeur, exemple une variable relle :
double
*
ptrDouble;
ptrDouble = (double
*
) malloc(sizeof(double));
Lallocation de la variable associe un pointeur est quivalente lallocation dun tableau contenant une
valeur.
Remarque : en utilisant cette allocation il nexiste pas de nom explicite de la variable. On peut accder cette
dernire uniquement en utilisant loprateur .
Libration de la mmoire : La libration de la mmoire se fait laide de la fonction free :
void free (void
*
ptr); /
*
prototypage de la fonction free
*
/
Il faut passer uniquement ladresse de la premire case mmoire alloue dynamiquement avec malloc. Cette
fonction na pas besoin de connatre le nombre de cases alloues car le systme lors de lallocation dynamique
enregistre cette information.
Attention : Il faut appeler le mme nombre de fois la fonction free et la fonction malloc. Il est aussi
conseiller de copier la valeur NULL dans pointeur dont on a libr la mmoire.
5 Tableaux bidimensionnel
5.1 Tableau 2D statique
Dclaration :
<type> nomTab[nbElements1][nbElements2];
<type> type des lments du tableau.
nomTab nom du tableau.
nbElements1 nombre dlments du tableau selon laxe 1.
nbElements2 nombre dlments du tableau selon laxe 2.
Initialisation : Linitialisation est semblable au cas monodimensionnel. Par exemple si on veut initialiser un
tableau de double de 2 3 valeurs on doit crire la ligne suivante :
double tabDouble[2][3]=

{2.5,6.8,7.02},{6.23,5.21,4.85}

;
Laccs aux variables du tableau 2D se fait laide de deux crochets :
tabDouble[1][2]=6.25;
5.2 Tableau 2D dynamique
Lorganisation de la mmoire vue du processeur est monodimensionnelle. La mmoire peut tre reprsen-
te comme un vecteur de trs grande dimension, o la position dans ce vecteur correspond ladresse. Pour
accder la mmoire comme dans un tableau bidimensionnel il faut pouvoir sauter plusieurs cases mmoires
uniquement en incrmentant lindice de ligne. Pour cela on utilise un tableau de pointeurs qui stocke ladresse
du dbut de chaque ligne. Lallocation dynamique dun tableau 2D dentiers 5 8 se fait de la faon suivante :
T. Rodet IFIPS S5
C dans la poche 15
int indice; int nbLignes=5;
int nbColonnes=8;
int
**
tab2DInt;
tab2DInt = (int
**
) malloc(nbLignes
*
sizeof(int
*
));
for(indice=0;indice<nbLignes;indice ++)
tab2DInt[indice]=(int
*
) malloc(nbColonnes
*
sizeof(int));
Loccupation mmoire du tableau ci-dessus est reprsente sur la gure 10.
Mmoire
tab2DInt
tab2DInt[2]
FIG. 10 Reprsentation de la mmoire dun tableau dynamique 2D
5.2.1 Libration de la mmoire
An de librer correctement la mmoire alloue dynamiquement, il faut excuter les lignes suivantes :
int indice;
int nbLignes=5;
int nb Colonnes=8;
int
**
tab2DInt;
.
.
.
for(indice=0; indice<nbLignes; indice ++)
{
free(tab2DInt[indice]);
tab2DInt[indice]=NULL;
}
free(tab2DInt);
Attention : Il faut absolument librer les zones mmoires dont ladresse est stocke dans le tableau de
pointeurs avant de librer ce dernier.
5.2.2 Cas particulier : le tableau de chanes de caractres
Comme une chane de caractres est reprsente en langage C comme un tableau de caractres, un tableau
de chanes de caractres possde la mme structure en mmoire quun tableau bidimensionnel. Trouvez ci-
dessous des lignes permettant de copier le contenu dun tableau de chanes de caractres allou de manire
statique dans un tableau de chanes de caractres allou dynamiquement.
T. Rodet IFIPS S5
C dans la poche 16
char tabCharStat[3][26]={"anticonstitutionnellement","bonjour","paresse"};
char
**
tabCharDyn;
int indice;
int nbChaine=3;
int tailleChaine;
tabCharDyn = (char
**
) malloc(nbChaine
*
sizeof(char
*
));
for(indice=0;indice<nbChaine;indice++)
{
tailleChaine=strlen(tabCharStat[indice])+1;
tabCharDyn[indice]=(char
*
) malloc(tailleChaine
*
sizeof(char));
strcpy(tabCharDyn[indice],tabCharStat[indice]);
{
Le tableau dynamique occupe une place plus faible en mmoire car on alloue uniquement la place ncessaire
chaque chane. En procdant un calcul simple, on trouve que le tableau statique occupe 78 octets alors que
le tableau dynamique nen occupe que 54.
6 Structures et types structurs
Les structures dsignent des types de donnes composes, cest dire contenant plusieurs composantes, qui
peuvent tre de natures diffrentes. Elles sont opposer aux tableaux dont les composantes sont de mme type.
Chaque structure est dnie par le programmateur en fonction de ses besoins. Elles permettent entre autre
de coder en partie les objets que vous allez voir en UML.
6.1 Dnir une structure
La syntaxe est la suivante :
struct <identifiant>
{
int nombre;
double prix;
char nom[30]; /
*
exemple de contenu
*
/
};
6.2 Dclaration dune structure
Pour dclarer une variable ayant cette structure, il faut crire :
struct <identifiant> variable;
Comme cette dclaration utilise un nom assez long et peu lisible, on va utiliser la possibilit en C de dnir
de nouveaux types.
6.3 Dnir de nouveaux types
La commande typedef permet de donner de nouveaux noms aux types dj dnis, par exemple :
typedef unsigned char BYTE;
typedef int
*
ptrInteger;
Dans la suite du programme on pourra dnir des variables de type BYTE.
T. Rodet IFIPS S5
C dans la poche 17
6.3.1 Application aux structures
typedef struct <identifiant>
{
int nombre;
double prix;
char nom[30]; /
*
exemple de contenue
*
/
}<nouveauType>;
La dclaration des variables est alors beaucoup plus simple : on dclare les variables de type structure
comme une variable de type natif.
<nouveauType> variable;
6.4 Manipulation de variables de type structure
6.4.1 Accs direct
Lorsque le non de la variable de type structure est connu, laccs aux diffrentes composantes de la structure
se fait laide de loprateur point (.) selon la syntaxe suivante :
nomVariable.nomChamp
Exemple :
typedef struct structProd
{
int nombre;
double prix;
char nom[30]; /
*
exemple de contenu
*
/
} produit;
.
.
.
produit cola={0,1.5,"breizcola"};
.
.
.
cola.nombre=10;
.
.
.
strcpy(cola.nom,"Pepsi");
6.4.2 Accs indirect, travers un pointeur sur la variable de type structure
Lorsquon accde aux champs de la structure travers un pointeur, on utilise loprateur che (->) la
place de loprateur point.
Exemple :
T. Rodet IFIPS S5
C dans la poche 18
typedef struct structProd
{
int nombre;
double prix;
char nom[30]; /
*
exemple de contenu
*
/
} produit;
.
.
.
produit
*
ptrProd;
ptrProd= (produit
*
) malloc(sizeof(produit));
ptrProd->nombre=10;
ptrProd->prix=2.43;
strcpy(ptrProd->nom,"Pepsi");
6.4.3 Affectation
La seule opration qui existe sur les structures, cest lopration daffectation du contenu dune variable
de type structure dans une autre variable de mme type. Il nexiste pas de rgles de transtypage ni dautres
oprations comme pour les types natifs.
Exemple :
typedef struct structProd
{
int nombre;
double prix;
char nom[30]; /
*
exemple de contenu
*
/
} produit;
.
.
.
produit cola=0,1.5,"breizcola";
produit soda;
.
.
.
soda=cola;
.
.
.
printf("le soda contient du %s",soda.nom );
6.4.4 Fonctions ayant des paramtres de type structure
Les variables de type structure peuvent tre passes en paramtre des fonctions. Le type structure peut aussi
tre la variable de retour.
Exemple :
T. Rodet IFIPS S5
C dans la poche 19
typedef struct structProd
{
int nombre;
double prix;
char nom[30]; /
*
exemple de contenu
*
/
} produit;
.
.
.
void AfficheProd(produit param)
{
printf("Le produit %s coute %lf \n",param.nom,param.prix);
printf("Il en reste %d en stock \n",param.nombre);
}
7 Flux dentre sortie
Les ux dentre sortie permettent au programme dchanger des informations avec lutilisateur ou avec
dautres programmes. Linteraction avec les utilisateurs se fait travers le clavier et lcran (resp. entre stan-
dard et sortie standard). Pour les changes avec dautres programmes ou dautres systmes dinformations, on
utilise des chiers. Toutes les oprations dentre sortie se font laide de fonctions codes dans la bibliothque
stdio.h (abrviation de standard input output).
7.1 Entre sortie standard
Dnitions : Lentre standard correspond au clavier de lordinateur, en langage C il se nomme stdin
(abrviation de standard input).
La sortie standard correspond lcran de lordinateur, en langage C il se nomme stdout (abrviation de
standard output).
On ne lit et crit resp. sur lentre et la sortie standard que des caractres. Quand on veut afcher le contenu
dune variable lcran, il faut convertir son contenu en caractres. De mme pour lire une valeur au clavier et
la mettre dans une variable, il faut convertir la chane de caractres saisie.Les rgles de conversion dpendent
principalement du type de la variable. Lutilisation dune rgle plutt quune autre est spcie par lutilisateur
travers des formats. Ces formats sont construits de la faon suivante :
%<taille>.<prec><type>
<taille> : nombre minimal de caractres afcher (facultatif).
<prec> : nombre de caractres afcher aprs la virgule (facultatif).
<type> : voir tableau 2.
Format Type Description
%c char caractre sign
%s char * chane de caractres
%d int entier sign
%u unsigned int entier non sign
%f oat rel simple prcision
%lf double rel double prcision
TAB. 2 Les principaux formats dcriture structure.
criture lcran : Lcriture sur lcran se fait laide de la fonction printf.
Syntaxe :
T. Rodet IFIPS S5
C dans la poche 20
int printf(" text1 <format1> ...<formatN> ",variable1,...,variableN);
La valeur de retour est le nombre de variables crites avec succs.
Exemple :
int valeur =6;
int carre= valeur
*
valeur;
printf("Le carre de %d vaut %d \n",valeur,carre);
Le code ci-dessus crit dans la console :
Le carre de 6 vaut 36
Lecture sur le clavier : La lecture sur le clavier se fait travers une mmoire tampon. Tous les caractres
taps au clavier sont stocks dans une mmoire tampon. Cette mmoire est lue quand lutilisateur tape sur la
touche "Entre" (retour chariot). La lecture sur le clavier se fait laide de la fonction scanf.
Prototypage :
int scanf(" <format1> ...<formatN> ",addrVar1,...,addrVarN);
o addrVar1 est ladresse de la variable dans laquelle nous voulons copier la valeur saisie au clavier. La
valeur de retour contient le nombre de valeurs lues avec succs.
7.2 Accs un chier texte
Remarque : un chier permet de ranger linformation uniquement de manire squentielle. Linsertion
dinformations au milieu dun chier nest donc pas trs facile.
7.2.1 Ouverture dun chier
Cest louverture du chier que lon dtermine la nature du chier que lon veut traiter (binaire ou texte),
ainsi que le type dopration quon va effectuer sur ce dernier (lecture seule, cration, modication).
Louverture du chier se fait laide de la fonction fopen. Elle possde le prototype suivant :
FILE
*
fopen(char
*
nom_fichier, char
*
mode);
fopen ouvre le chier nomm nom_fichieret renvoie ladresse dune variable de type structure FILE.
Cette structure permet de dcrire ltat du chier. Sil y a une erreur, ladresse renvoye est nulle. La chane de
caractres mode permet de spcier le mode douverture du chier (voir tableau 3).
Mode Description
rt Ouverture dun chier texte en lecture seule
rb Ouverture dun chier binaire en lecture seule
wt Cration dun chier texte en criture seule (crase le chier sil existe )
wb Cration dun chier binaire en criture seule (crase le chier sil existe )
at Ouverture dun chier texte et ajout en n de chier (criture seule)
ab Ouverture dun chier binaire et ajout en n de chier (criture seule)
r+t Ouverture dun chier texte pour des modications (lecture + criture)
r+b Ouverture dun chier binaire pour des modications (lecture + criture)
w+t Cration dun chier texte en lecture et criture (crase le chier sil existe )
w+b Cration dun chier binaire en lecture et criture (crase le chier sil existe )
a+t Ouverture dun chier texte en lecture criture, cration si le chier nexiste pas
a+b Ouverture dun chier binaire en lecture criture, cration si le chier nexiste pas
TAB. 3 Les diffrents modes douverture dun chier.
T. Rodet IFIPS S5
C dans la poche 21
7.2.2 criture dans un chier texte
Cest la fonction fprintf qui permet dcrire de manire formate dans un chier texte.
Prototype :
int fprintf(FILE
*
fid," text <format1> ...<formatN>",var1,...,varN);
Cette fonction est semblable la fonction printf, la seule diffrence cest quelle crit dans le chier
associ fid.
Remarque : fprintf(stdout,"toto"); est quivalent printf("toto");
7.2.3 Lecture dans un chier texte
La lecture formate dans un chier est obtenue grce la fonction fscanf.
Prototype :
int fscanf(FILE
*
fid,"<format1> ...<formatN>",addrVar1,...,addrVarN);
Cette fonction est semblable la fonction scanf, la seule diffrence cest quelle crit dans le chier
associ fid.
Remarque : fscanf(stdin,"%d ",&varInt); est quivalent scanf("%d",&varInt);
7.2.4 Fermeture du chier
Pour que lcriture soit effectu physiquement sur le disque, il faut fermer le chier en utilisant la fonction
fclose.
Prototype :
int fclose(FILE
*
fid);
La valeur de retour est gale 0 si tout sest bien pass.
7.3 Accs un chier binaire
An douvrir et de fermer un chier binaire on utilise les mmes fonctions que pour un chier texte. Par
contre il faut le spcier dans le mode douverture (voir tableau 3). Les fonctions de lecture et dcriture
diffrent dans le cas binaire.
7.3.1 criture dans un chier binaire
La fonction fwrite permet de recopier des octets de la mmoire vers le chier ouvert. Cette copie se fait
sans interprtation contrairement la fonction fprintf.
Prototypage :
int fwrite((void
*
)ptr, int tailleEnreg, int nbEnreg, FILE
*
fid);
Les arguments de cette fonction sont :
ptr le pointeur contenant ladresse de dbut de la zone mmoire que lon veut crire dans le chier.
tailleEnreg contient la taille des enregistrements. An de renseigner cette valeur on utilise souvent
la fonction sizeof.
nbEnreg contient le nombre denregistrements. La taille de la zone mmoire enregistre dans le chier
est gale tailleEnreg nbEnreg.
Le dernier paramtre est lindentiant du chier.
La valeur de retour contient le nombre denregistrements crits dans le chier si aucune erreur nest surve-
nue.
T. Rodet IFIPS S5
C dans la poche 22
7.3.2 Lecture dans un chier binaire
La fonction fread permet de lire le contenu des chiers qui ont t crits avec la fonction fwrite.
Prototypage :
int fread((void
*
)ptr, int tailleEnreg, int nbEnreg, FILE
*
fid);
Ses arguments sont identiques la fonction fwrite. ptr contient ladresse de la zone mmoire partir
de laquelle on stocke le contenu du chier. Attention, il faut sassurer que lon a bien rserv assez de place
mmoire.
La valeur de retour contient le nombre denregistrements lus dans le chier si aucune erreur nest survenue.
7.3.3 Dplacement dans le chier
An de se dplacer dans un chier, il faut utiliser la fonction fseek.
Prototypage :
int fseek(FILE
*
fid, long depl, int position);
Cette fonction admet trois arguments :
Le descripteur du chier fid.
Le dplacement voulu dans le chier en octet depl.
La position partir de laquelle on se dplace position. Il y a trois positions possibles dnies comme
constantes dans le chier stdio.h :
SEEK_SET dplacement partir du dbut du chier (depl doit tre positif).
SEEK_CUR dplacement partir de la position courante dans le chier.
SEEK_END dplacement partir de la n du chier (depl doit tre ngatif).
Cette fonction retourne 0 si le dplacement sest bien pass.
Remarque : ftell est une fonction qui permet de connatre sa position par rapport au dbut du chier en
octet (voir laide en ligne).
7.3.4 Dtection de la n du chier
La fonction feof (abrviation de function end of file) permet de dterminer si la n du chier est dpasse.
Elle possde le prototype suivant :
int feof(FILE
*
fid);
Cette fonction a comme paramtre le descripteur de chier et elle renvoie 0 si la n du chier nest pas
dpasse.
Remarque : La fonction renvoie une valeur diffrente de zro uniquement quand la n du chier est dpasse.
Lorsquon exactement la n du chier la fonction feof revoie 0.
T. Rodet IFIPS S5

S-ar putea să vă placă și