Vous êtes sur la page 1sur 147

Département d'Informatique

Module I132 :
Algorithmique et programmation 2

Pr. A. OUSSOUS
ahmed.oussous@fstm.ac.ma
Parcours MIP (S3)

19 septembre 2022
1
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
La programmation modulaire
(les fonctions)

2
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Introduction

Comme tous les langages, C permet de découper un programme en


plusieurs parties nommées souvent modules qui se justie pour de
multiples raisons :
Un programme écrit dans un seul bloc devient dicile à
comprendre dès qu'il dépasse une ou deux pages de code.
La programmation modulaire permet d'éviter des séquences
d'instructions répétitives.

3
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Introduction

Dans beaucoup de langages, on trouve deux sortes de "modules", à


savoir :
Les fonctions : assez proches de la notion mathématique.
Une fonction reçoit des arguments (paramètres) et elle fournit
un résultat.
Les procédures : qui élargissent la notion de fonction. Elles
ne possèdent pas de valeurs de retour mais elles peuvent
disposer d'arguments.
⇒ En langage C, il n'existe qu'une seule sorte de module, il s'agit
des fonctions. On parle ainsi des fonctions avec valeur de retour et
des fonctions sans valeur de retour.

4
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exemples de dénition et d'utilisation des fonctions
La fonction mathématique suivante
f : R × R −→ R
(x, y ) −→ x + y
est dénie en langage c par :
main () {
float f ( float , float ) ; /* D é claration de f */
float z ;
z = f (5 ,4) ; /* Appel de la fonction f */
printf ( " % f " ,z ) ;
}
/* D é finition de la fonction f */
float f ( float x , float y ) {
float r ;
r = x+y;
return r ;
}
5
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exemples de dénition et d'utilisation des fonctions

Ce programme est divisé en deux modules (fonctions) :


 Le programme principal formé d'un bloc (la fonction main)
 La fonction f possèdant la structure voisine de celle de main :
float f ( float x , float y )
| | | |
type valeur nom de la 1 er arg 2 é me arg
de retour fonction ( float ) ( float )
I La déclaration de la fonction f dans main sert à prévenir le compila-
teur que f est une fonction et elle lui précise le type de ses arguments
ainsi que celui de sa valeur de retour.
 Cette déclaration n'est obligatoire que si elle est dénie
après son appel.
I oat r précise que, pour eectuer son travail, f a besoin d'une
variable locale de type oat nommée r .
I return r précise la valeur que fournira la fonction.
6
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exemples de dénition et d'utilisation des fonctions

Soit la fonction absolue calculant la valeur absolue d'un réel :


absolue : R −→ R+

si x ≥ 0
(
x
x −→
−x sinon

float absolue ( float x ) {


float r ;
if (x >=0)
r=x ;
else
r=-x ;
return r ;
}

7
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exemples de dénition et d'utilisation des fonctions

2ème méthode :
float absolue ( float x ) {
if (x >=0)
return x ;
else
return -x ;
}
 L'instruction return peut apparaître à plusieurs reprises dans une
fonction.
 L'instruction return peut mentionner n'importe quelle expression.
Exemple : la fonction f dénie plus haut peut être dénie comme
suit :
float f ( float x , float y ) {
return x + y ;
}
8
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exemples de dénition et d'utilisation des fonctions
En plus de retourner la valeur, return interrompt également l'exécu-
tion de la fonction en revenant dans la fonction qui l'a appelée.
float absolue ( float x ) {
if (x >=0) {
return x ;
printf ( " Positif " ) ;
}
else {
return -x ;
printf ( " N é gatif " ) ;
}
}
I Les instructions printf("Positif") et printf("Négatif") ne seront
jamais éxecutées. D'où la dénition suivante :
float absolue ( float x ) {
if (x >=0) return x ;
return -x ;
9
}
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exemples de dénition et d'utilisation des fonctions
 Fonction sans valeur de retour et sans arguments :
void Bienvenue () { /* Message de bienvenue */
printf ( " Bienvenue chers clients " ) ;
 Fonction avec arguments et sans valeur de retour :
void Bienvenue ( int n ) { /* Bienvenue n fois */
int i ;
for ( i =1; i <= n ; i ++)
printf ( " Bienvenue chers clients \ n " ) ;
}
 Fonction avec valeur de retour et sans arguments :
double pi () { /* Valeur approximative de pi */
return 3 ,141592653589793238462643383279;
}
Remarque : main est une fonction sans argument et sans valeur
de retour. Elle devrait donc avoir pour en-tête void main(void).
Certains compilateurs fournissent un  warning  sinon. 10
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les variables globales
Les variables globales sont des variables déclarées à l'extérieur de
toute fonction.
Elles ne sont connues que dans la partie du programme source
suivant leur déclaration.
Elles sont partagées par plusieurs fonctions.
Exemple :
int n ;
main () {
I La variable n peut être utilisée dans toutes
....
} les fonctions.
int p ; I La variable p ne peut être utilisée que dans
void f () { les fonctions f et g .
....
}
void g () {
....
}
11
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les variables locales
Les variables locales sont des variables déclarées au sein d'une fonc-
tion (qui pouvait être main).
Elles ne sont connues qu'à l'intérieur de la fonction où elles
sont déclarées.
I Leur portée est donc limitée à cette fonction.
Elles n'ont aucun lien avec d'autres variables locales d'autres
fonctions.
Exemple :
I La variable p de main n'a aucun rapport
int n ; avec la variable p de f .
main () {
I La variable n de f n'a aucun rapport avec
int p ;
.... la variable globale n.
} I Il impossible d'utiliser la variable global n
void f () { dans f .
int p ;
int n ;
}
12
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les variables locales : exemple

# include < stdio .h >


int triple ( int nombre ) ;

int main ( int argc , char * argv [])


{
printf ( " Le triple de 15 est % d \ n " , triple
(15) ) ;
printf ( " Le triple de 15 est % d " , resultat ) ;
return 0;
}

int triple ( int nombre )


{
int resultat = 0;
resultat = 3 * nombre ;
return resultat ;
}
13
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les variables locales statiques

 Les variables locales ont une durée de vie limitée à celle d'une
exécution de la fonction dans laquelle elles gurent.
 Un nouvel espace mémoire leur est alloué à chaque entrée dans la
fonction et libéré à chaque sortie.
⇒ Les valeurs des variables locales ne sont pas conservées d'un
appel au suivant. Classe d'allocation automatique
I Pour conserver la valeur d'une variable locale d'un appel au sui-
vant, il sut de la déclarer à l'aide du mot-clé static .
⇒ Les variables locales de classe statique sont, par défaut,
initialisées à zéro.

14
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les variables locales statiques

Exemple d'utilisation de variable locale statique :


# include < stdio .h >
main () {
void fct ( void ) ;
fct () ;
fct () ;
fct () ;
}
void fct ( void ) {
static int i ;
i ++ ;
printf ( " Appel num é ro : % d \ n " , i ) ;
}
Appel numéro : 1
Appel numéro : 2
Appel numéro : 3
15
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exercice

Ecrire :
- une fonction, nommée f1, se contentant d'acher "bonjour" (elle
ne possédera aucun argument ni valeur de retour),
- une fonction, nommée f2, qui ache "bonjour" un nombre de fois
égal à la valeur reçue en argument (int) et qui ne renvoie aucune
valeur,
- une fonction, nommée f3, qui fait la même chose que f2, mais qui,
de plus, renvoie la valeur (int) 0.
Ecrire un petit programme appelant successivement chacune de ces
trois fonctions, après les avoir convenablement déclarées sous forme
d'un prototype

16
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Solution

void f1 ( void )
{ printf ( " bonjour \ n " ) ;
}
void f2 ( int n )
{ int i ;
for ( i =0 ; i < n ; i ++)
printf ( " bonjour \ n " ) ;
}
int f3 ( int n )
{ int i ;
for ( i =0 ; i < n ; i ++)
printf ( " bonjour \ n " ) ;
return i ;
}

17
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Solution

main ()
{
void f1 ( void ) ;
void f2 ( int ) ;
int f3 ( int ) ;
f1 () ;
f2 (3) ;
f3 (3) ;
}

18
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exercice

Qu'ache le programme suivant ?


# include < stdio .h >
int n =5 ;
main ()
{
void fct ( int p ) ;
int n =3 ;
fct ( n ) ;
}
void fct ( int p )
{
printf ( " % d % d " , n , p ) ;
}

19
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Exercice

1- Écrire une fonction qui renvoie 1 si un nombre entier passé en


paramètre est impair, 0 sinon. Son prototype est donc : int estIm-
pair(int nb). Écrire également son programme de test (main).
2- Ecrire une fonction MIN et une fonction MAX qui déterminent le
minimum et le maximum de deux nombres réels. Ecrire un programme
se servant des fonctions MIN et MAX pour déterminer le minimum
et le maximum de quatre nombres réels entrés au clavier.

20
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Solution

# include < stdio .h >


int estImpair ( int nb ) ;
int main ()
{
for ( int i =0; i <6 ; i ++) {
if ( estImpair ( i ) )
printf ( " % d est impair \ n " , i ) ;
else
printf ( " % d est pair \ n " , i ) ;
}
return 0;
}
int estImpair ( int nb ) {
if ( nb % 2 == 0)
return 0;
else
return 1;
}
21
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Solution

# include < stdio .h >


main ()
{
/* Prototypes des fonctions appel é es */
double MIN ( double X , double Y ) ;
double MAX ( double X , double Y ) ;
/* Variables locales */
double A ,B ,C , D ;
/* Traitements */
printf ( " Introduire 4 r é els : " ) ;
scanf ( " % lf % lf % lf % lf " , &A , &B , &C , & D ) ;
printf ( " Le minimum des 4 r é els est % f \ n " ,
MIN ( MIN (A , B ) , MIN (C , D ) ) ) ;
printf ( " Le maximum des 4 r é els est % f \ n " ,
MAX ( MAX (A , B ) , MAX (C , D ) ) ) ;
return 0;
}
22
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Solution

double MIN ( double X , double Y )


{
if (X < Y )
return X ;
else
return Y ;
}

double MAX ( double X , double Y )


{
if (X > Y )
return X ;
else
return Y ;
}

23
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Solution

/* ou bien */

double MIN ( double X , double Y )


{
return (X < Y ) ? X : Y ;
}

double MAX ( double X , double Y )


{
return (X > Y ) ? X : Y ;
}

24
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives

Le langage C autorise la récursivité des appels de fonctions. Celle-ci


peut prendre deux aspects :
Récursivité directe : une fonction comporte, dans sa
dénition, au moins un appel à elle-même,
Récursivité croisée : l'appel d'une fonction entraîne celui
d'une autre fonction qui, à son tour, appelle la fonction initiale.
Exemple : la fonction factorielle récursive

(−→ N
fact : N long fact ( long n ) {
1 si n = 0 if ( n ==0)
n −→ return 1;
n × fact(n − 1) sinon return n * fact (n -1) ;
}

25
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives et itératives

Soit la suite suivante :

U0 = 2
(

Un = Un−1 + 3 si n 1
 Fonction itérative :
int u ( int n ) {
int i , s ;
s =2;
for ( i =1; i <= n ; i ++)
s = s +3 ;
return s ;
}

26
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives et itératives

Soit la suite suivante :


U0 = 2
(

Un = Un−1 + 3 si n 1
 Fonction récursive :
int u ( int n ) {
if ( n ==0)
return 2 ;
return u (n -1) +3 ;
}

27
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives et itératives

Soit la fonction puissance suivante :


p : R × N −→ R
(x, n) −→ x n
Fonction itérative :
float p ( float x , int n ) {
float p =1;
int i ;
for ( i =1; i <= n ; i ++)
p=p*x ;
return p ;
}
 Une fonction est dite itérative s'elle est dénie en utilisant une
boucle.
28
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives et itératives

Même fonction dénie par une relation de récurrence :


p : R × N −→ R
1 si n = 0
(
(x, n) −→
x ∗ p(x, n − 1) sinon

float p ( float x , int n ) {


if ( n ==0)
return 1;
return x * p (x ,n -1) ;
}
 Une fonction est dite récursive s'elle est dénie à base d'une rela-
tion de récurrence.
29
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives et itératives : exercice

Écrire la fonction récursive somme qui calcule la somme : 1 + 2 +


... + n

30
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les fonctions
Les fonctions récursives et itératives : exercice

# include < stdio .h >

int somme ( int n ) {


if (n <=0 )
return 0;
else
return ( n + somme ( n - 1) ) ;
}

int main () {
int a = 3;
printf ( " la somme de la suite est % d " , somme (
a));

return 0;
}

31
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs

32
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs

Un tableau est un ensemble d'éléments de même type désignés par


un identicateur unique et où chaque élément est repéré par un in-
dice précisant sa position au sein de l'ensemble.
Exemple :Soit T un tableau d'entiers suivant :
T[0] T[7]
↓ ↓
4 15 10 6 45 13 17 9
Un pointeurs est une variable destinée à contenir des adresses
d'autres objets (variables, fonctions...).
Exemple : Soit n un entier et adr la variable qui contient son
adresse :
0XA23 −→ 13
adr n
33
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux

Déclaration :
int t [20] ;
I Cette déclaration réserve l'emplacement pour 20 éléments de type
int dont chaque élément est repéré par sa position dans le tableau,
nommée indice .
I La première position porte le numéro 0. Ici, donc, les indices vont
de 0 à 19.
I Le premier élément du tableau sera désigné par t[0], le troisième
par t[2], le dernier par t[19].
I Attention au débordement d'indice : Désigner un indice au delà
du tableau implique un accès à un emplacement situé avant ou après
le tableau.

34
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux

 Régle No 1 : Les éléments de tableau


Un élément de tableau peut être traité comme n'importe quelle autre
variable. Ainsi les instructions suivantes sont correctes :
t [2] = 5;
t [3]++ ;
--t [ i ] ;
printf ( " % d " ,t [4]) ;
scanf ( " % d " ,& t [ i ]) ;
En revanche si t 1 et t 2 sont des tableaux d'entiers, il n'est pas
possible d'écrire :
t1 = t2 ;
en fait, le langage C n'ore aucune possibilité d'aectations globales
de tableaux.
35
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux
 Régle No 2 : Les indices
Un indice peut prendre la forme de n'importe quelle expression arith-
métique de type entier . Par exemple, si n, p, k et j sont de type int ,
ces notations sont correctes :
t [n -3] ;
t [3* p -2* k + j % k ] ;
 Régle No 3 : La dimension d'un tableau
La dimension d'un tableau (son nombre d'éléments) ne peut être
qu'une constante ou une expression constante.
Exemples :
# define N 50 main () {
main () { const int N =50;
int t [ N ] ; int t [ N ] ;
float h [2* N -1] ; float h [2* N -1] ;
} }

36
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux
Exemple :
# include < stdio .h >
main () {
int i , som ;
float moy ;
int t [5] ;
/* Lecture des notes */
for ( i =0 ; i <5 ; i ++) {
printf ( " Note No % d : " , i +1) ;
scanf ( " % d " , & t [ i ]) ;
}
/* Calcul de la somme des notes */
for ( i =0 , som =0 ; i <5 ; i ++)
som += t [ i ] ;
moy = som /5 ; /* Calcul de la moyenne */
printf ( " Moyenne classe : %.2 f \ n " , moy ) ;
}
37
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux
Supposons que le nombre d'étudiant a changé ⇒ plusieurs modi-
cations à faire, d'ou l'intérêt d'utiliser les constantes.
# include < stdio .h >
# define N 10
main () {
int i , som ;
float moy ;
int t [ N ] ;
/* Lecture des notes */
for ( i =0 ; i < N ; i ++) {
printf ( " Note No % d : " , i +1) ;
scanf ( " % d " , & t [ i ]) ;
}
/* Calcul de la somme des notes */
for ( i =0 , som =0 ; i < N ; i ++) som += t [ i ] ;
moy = som / N ; /* Calcul de la moyenne */
printf ( " Moyenne classe : % f \ n " , moy ) ;
} 38
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux à plusieurs indices (Les matrices)

Déclaration :
int M [4][3];
I Cette déclaration réserve un tableau de 12 (4 x 3) entiers.
I Un élément de ce tableau est repéré par deux indices comme dsuit :
M [ indice_ligne ][ indice_colonne ]
I Attention au débordement d'indice.
Exemples :
int i =2 , j =1;
12 3 43
 
M [0][0] ; --> 12
M [ i + j ][0] ; --> 8
 7 5 6 
4 13 1
 
M [ j ][ i ] ; --> 6  
M [ i + j ][ i ] ; --> 9 8 16 9

39
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Initialisation des tableaux à un indice

 Comme les variables scalaires, les tableaux peuvent être initialisés


au moment de la déclaration.
int T [5] = {10 , 20 , 5 , 0 , 3} ;
 Il est possible de ne mentionner que les premières valeurs :
int T [5] = {10 , 20} ;
int T [5] = {10 , 20 , 5} ;
⇒ Les valeurs manquantes seront, suivant la classe d'allocation
du tableau, initialisées à zéro (statique) ou aléatoires (automatique).

 Il est possible d'omettre la dimension du tableau, celle-ci est dé-


terminée par le compilateur par le nombre de valeurs énumérées dans
l'initialisation.
int T [] = {10 , 20 , 5 , 0 , 3} ;

40
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux : exemple

41
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux : exemple

42
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Initialisation des tableaux à deux indices

Soit la matrice suivante :


1 2 3 4
 
 5 6 7 8 
9 10 11 12
 Ces deux déclarations sont equivalentes :
int M [3][4]={{1 ,2 ,3 ,4} ,{5 ,6 ,7 ,8} ,{9 ,10 ,11 ,12}};
int M [3][4]={1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12};
⇒ La première forme revient à considérer le tableau comme formé
de trois tableaux de quatre éléments chacun. La seconde, elle, ex-
ploite la manière dont les éléments sont eectivement rangés en mé-
moire et elle se contente d'énumérer les valeurs du tableau suivant
cet ordre.
43
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux - Exercice

Écrire un programme qui demande 10 nombres entiers à l'utilisateur,


les range dans un tableau avant d'en rechercher le plus grand et le
plus petit.
Acher le tableau, ainsi que le nombre le plus petit et le plus grand.

44
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux - Solution

# include < stdio .h >


int main () {
const int TAB_SIZE = 10;
int tNombres [ TAB_SIZE ];

printf ( " Entrez les nombres ( entiers ) du


tableau \ n " ) ;
for ( int i = 0 ; i < TAB_SIZE ; i ++) {
printf ( " Nombre % d /10 : " , i +1) ;
scanf ( " % d " , & tNombres [ i ]) ;
}

// Rechercher le plus petit nombre


int nbMin = tNombres [0];
for ( int i = 1 ; i < TAB_SIZE ; i ++) {
if ( tNombres [ i ] < nbMin )
nbMin = tNombres [ i ];
}
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
45
Les tableaux et les pointeurs
Les tableaux - Solution

// Rechercher le plus grand nombre


int nbMax = tNombres [0];
for ( int i = 1 ; i < TAB_SIZE ; i ++) {
if ( tNombres [ i ] > nbMax )
nbMax = tNombres [ i ];
}
// Aficher le tableau
for ( int i = 0 ; i < TAB_SIZE ; i ++)
printf ( " , % d " , tNombres [ i ]) ;

printf ( " \ nLa valeur minimale est : % d " ,


nbMin ) ;
printf ( " \ nLa valeur maximale est : % d " ,
nbMax ) ;

return 0;
}
46
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux - Exerice

- Ecrire un programme qui met à zéro les éléments de la diagonale


principale d'une matrice carrée A donnée.
- Ecrire un programme qui eectue la transposition tA d'une matrice
A de dimensions N et M en une matrice de dimensions M et N. La
matrice transposée sera mémorisée dans une deuxième matrice B qui
sera ensuite achée.

47
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux - solution

48
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux - solution

49
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs : L'opérateur &
Nous avons déjà rencontré l'opérateur & dans la fonction scanf pour
désigner l'adresse d'une variable.
D'une manière générale, il est possible de manipuler des adresses par
l'intermédiaire de variables nommées pointeurs.
Exemple :
int * ad ; /* D é claration du pointeur ad */
int n ;
n = 20;
ad = & n ; /* Affectation de l ' adresse de n à ad */

La variable (pointeur) ad contient l'adresse de n (&n ici 0XFA4)


signie que ad est un pointeur sur la variable n. 50
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs : L'opérateur ∗
L'opérateur ∗ désigne le contenu de l'adresse qui le suit, autrement-
dit la variable ou l'emplacement mémoire pointé par cette adresse.
Exemple :
Soient les déclarations suivantes :
int * ad ; /* D é claration du pointeur ad */
int n ;
ad = & n ; /* Affectation de l ' adresse de n à ad */
Les instructions suivantes sont équivalentes :
n = 10 ;

* ad = 10 ;
Stocker la valeur 10 dans l'emplacement réservé pour n.

51
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs

Exemples :
Soient les déclarations suivantes :
int * ad1 , * ad2 ;
int n = 10 , p = 20 ;
ad1 = &n ;
ad2 = &p ;
Les instructions suivantes sont équivalentes :
* ad1 = * ad2 + 2 ; ⇔ n = p + 2 ;
* ad1 ++ ; ⇔ n ++ ;
* ad1 = * ad2 ; ⇔ n = p ;
Aectation de pointeurs :
ad1 = ad2
* ad1 = 40 ; ⇔ p = 40 ;
* ad2 = 40 ; ⇔ p = 40 ;
52
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
exemple
Quelles seront les valeurs des variables i, j et p après exécution des
instructions suivantes ?

53
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
exemple

54
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs : Incrémentation de pointeurs
Il faut noter qu'un pointeur est déni à la fois par une adresse en
mémoire et par un type (nombre d'octets pointés).
Soit la déclaration suivante :
int * ad1 , * ad2 ;
int n ;
L'expression suivante à un sens en langage c :
ad1 = & n ;
ad2 = ad1 + 1;
En eet, ad 1 est un pointeur sur un entier (4octets), l'expression
ad 1 + 1 (ad 2) représente l'adresse de l'entier suivant.

55
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs : Incrémentation de pointeurs

Soit la déclaration suivante :


double * ad1 , * ad2 ;
double n ;
L'expression suivante à un sens en langage c :
ad1 = & n ;
ad2 = ad1 + 1;
En eet, ad 1 est un pointeur sur un double (8octets), l'expression
ad 1 + 1 (ad 2) représente l'adresse de le double suivant.

56
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs- Exercice

57
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les pointeurs- Solution

58
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Transmission des arguments d'une fonction : transmission par valeur
1 main () {
2 void echange ( int , int ) ;
3 int n =10 , p =20 ;
4 printf ( " avant appel : n =% d p =% d \ n " , n , p ) ;
5 echange (n , p ) ;
6 printf ( " apr è s appel : n =% d p =% d " , n , p ) ;
7 }
8 void echange ( int a , int b ) {
9 int aux ;
10 printf ( " d é but echange : a =% d b =% d \ n " , a , b ) ;
11 aux = a ;
12 a = b ;
13 b = aux ;
14 printf ( " fin echange : a =% d b =% d \ n " , a , b ) ;
15 }
avant appel : n=10 p=20
début echange : a=10 b=20
fin echange : a=20 b=10
après appel : n=10 p=20 59
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Transmission des arguments d'une fonction : transmission par adresse

1 main () {
2 void echange ( int , int ) ;
3 int n =10 , p =20 ;
4 printf ( " avant appel n =% d p =% d \ n " , n , p ) ;
5 echange (& n , & p ) ;
6 printf ( " apr è s appel n =% d p =% d " , n , p ) ;
7 printf ( " \ n \ n " ) ;
8 }
9 void echange ( int * ad1 , int * ad2 ) {
10 int aux ;
11 aux = * ad1 ;
12 * ad1 = * ad2 ;
13 * ad2 = aux ;
14 }
avant appel n=10 p=20
après appel n=20 p=10
60
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Transmission des arguments d'une fonction : transmission par valeur VS adresse

- Dans le passage par valeur,une copie des arguments réels est trans-
mise aux arguments formels respectifs.
- Dans le passage par adresse, l'emplacement (adresse) des argu-
ments réels est transmis à des arguments formels, toute modication
apportée aux arguments formels se reétera également dans les ar-
guments réels.

61
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Le nom de tableau est un pointeur constant : cas des tableaux à un indice

L'identicateur d'un tableau, lorsqu'il est employé seul (sans indices


à sa suite), est un pointeur constant sur le début du tableau.
Exemple :
int T [5] ;

T ⇔ & T [0] ⇒ 0X0


T +1 ⇔ & T [1] ⇒ 0X4
T+i ⇔ &T[i]
*( T + i ) ⇔ T[i]

62
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Le nom de tableau est un pointeur constant : cas des tableaux à un indice

Exemple : Initialiser toutes les cases d'un tableau par zéro.

# include < stdio .h >


# define N 5
main () {
int T [ N ] , i ;
for ( i =0; i < N ; i ++)
T[i] = 0 ;
}
63
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Le nom de tableau est un pointeur constant : cas des tableaux à un indice
Exemple : Initialiser toutes les cases d'un tableau par zéro.

# include < stdio .h > # include < stdio .h >


# define N 5 # define N 5
main () { main () {
int T [ N ] , i , * p ; int T [ N ] , i ;
p = T ; for ( i =0; i < N ; i ++)
for ( i =0; i < N ; i ++) *( T + i ) = 0 ;
*( p + i ) = 0 ; }
}
64
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Le nom de tableau est un pointeur constant : cas des tableaux à un indice
Exemple : Initialiser toutes les cases d'un tableau par zéro.

# include < stdio .h >


# define N 5
main () {
int T [ N ] , i ;
int * p ;
for ( p = T , i =0 ; i < N ; i ++ , p ++)
*p = 0 ;
}
NB : Nous avons recopié la valeur de T dans un pointeur variable
nommé p. En eet, T est une adresse constante (T++ est invalide). 65
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Exercices

1- à laide de pointeurs, écrivez un programme qui demande à l'utilisa-


teur de remplir un tableau de 6 élements, puis le programme calcule
et ache la somme des éléments.
2- à laide de pointeurs, écrivez un programme qui demande à l'utili-
sateur de saisir 10 entiers qu'on stocke dans un tableau T. Ensuite, le
programme détermine et ache le minimum des éléments du tableau
T.

66
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Solutions

# include < stdio .h >


# include < stdlib .h >
int main () {
int T [6] , S ;
int * P ;
P=T;
printf ( " veuillez saisir les elements du tableau
: \n");
for ( P = T ; P < T +6; P ++) {
printf ( " T [% d ]= " , P - T ) ;
scanf ( " % d " ,P ) ;
}
S =0;
for ( P = T ;P < T +6; P ++) {
S = S +* P ; }

printf ( " La somme des elements du tableau est :


% d " ,S ) ;
}
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
67
Les tableaux et les pointeurs
Solutions

# include < stdio .h >


# include < stdlib .h >
int main () {
int T [10] , min ;
int * P ;
P=T;
printf ( " veuillez saisir les elements du tableau
: \n");
for ( P = T ; P < T +10; P ++) {
printf ( " T [% d ]= " , P - T ) ;
scanf ( " % d " ,P ) ; }
min =* P ;
for ( P = T +1; P < T +10; P ++) {
if ( min >* P )
min =* P ;}
printf ( " Le minimum des elements du tableau est
: % d " , min ) ;
}
68
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
La comparaison de pointeurs
Il est possible, en C, de comparer des pointeurs de même type.
Exemple : Ces deux programmes sont équivalents.
# include < stdio .h >
main () {
int T []={1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10};
int i ;
for ( i =10 ; i <10; i ++)
printf ( " % d " ,T [ i ]) ;
}

# include < stdio .h >
main () {
int T []={1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10};
int * p ;
for ( p = T ; p < T +10; p ++)
printf ( " % d " ,* p ) ;
}
69
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à un indice
Lorsque l'on place le nom d'un tableau en argument de la fonction,
on transmet nalement l'adresse du tableau à la fonction :
⇒ Les tableaux sont passés par adresse.
⇒ Il est donc possible de modier leurs élements dans la fonction.
Exemple :
# include < stdio .h > main () {
# define N 5 int A []={1 ,2 ,3 ,4 ,5};
void raz ( int T [ N ]) { int B []={3 ,6 ,2 ,9 ,1};
int i ; raz ( A ) ;
for ( i =0; i < N ; i ++) afficher ( A ) ;
T [ i ]=0; raz ( B ) ;
} afficher ( B ) ;
void afficher ( int T [ N ]) { }
int i ;
for ( i =0 ; i < N ; i ++)
printf ( " % d " ,T [ i ]) ;
}
70
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à un indice
 Tableau de taille xe :
void raz ( int T [5]) {
int i ;
for ( i =0; i <5; i ++) T [ i ]=0;
}
⇒ Cette fonction ne peut être appliquée que sur des tableaux de
taille 5.
main () {
int A []={1 ,2 ,3 ,4 ,5} , B []={1 ,2 ,3 ,4 ,5 ,6 ,7} , i ;
raz ( A ) ;
for ( i =0; i <5; i ++) printf ( " % d " ,A [ i ]) ;
raz ( B ) ;
for ( i =0; i <7; i ++) printf ( " % d " ,B [ i ]) ;
}
Affichage du tableau A : 0 0 0 0 0
Affichage du tableau B : 0 0 0 0 0 6 7
71
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à un indice
 Tableau de taille variable :
void raz ( int T [] , int N ) {
int i ;
for ( i =0; i < N ; i ++) T [ i ]=0;
}
⇒ Cette fonction peut être appliquée sur des tableaux de taille quel-
conque.
main () {
int A []={1 ,2 ,3 ,4 ,5} , B []={1 ,2 ,3 ,4 ,5 ,6 ,7} , i ;
raz (A ,5) ;
for ( i =0; i <5; i ++) printf ( " % d " ,A [ i ]) ;
raz (B ,7) ;
for ( i =0; i <7; i ++) printf ( " % d " ,B [ i ]) ;
}
Affichage du tableau A : 0 0 0 0 0
Affichage du tableau B : 0 0 0 0 0 0 0
72
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à un indice

 L'en-tête de raz peut être indiéremment écrit de l'une des ma-


nières suivantes :
void raz ( int T [10])
void raz ( int * T )
void raz ( int T [])
 Quel que soit l'en-tête employé, on peut, dans la dénition de la
fonction, utiliser indiéremment le formalisme tableau ou le forma-
lisme pointeur.
for ( i =0 ; i < N ; i ++) T [ i ] = 0 ;

for ( i =0 ; i < N ; i ++) *( T + i ) = 0 ;

for ( p = T ; p < T + N ; p ++) * p = 0 ;

for ( i =0 ; i < N ; i ++) T [ i ] = 0 ;


73
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à plusieurs indices
Exemple : Le formalisme tableau
void raz ( int M [2][3]) {
int i , j ;
for ( i =0; i <2; i ++)
for ( j =0; j <3; j ++)
M [ i ][ j ]=0;
}
void afficher ( int M [2][3]) {
int i , j ;
for ( i =0; i <2; i ++)
for ( j =0; j <3; j ++)
printf ( " % d " , M [ i ][ j ]) ;
}
main () {
int A [2][3]={{1 ,2 ,3} ,{4 ,5 ,6}};
raz ( A ) ;
afficher ( A ) ;
}
74
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à plusieurs indices

Exemple : Le formalisme pointeur


void raz ( int M [2][3]) {
int * p ;
for ( p = M [0]; p < M [0]+6; p ++)
* p =0;
}
void afficher ( int M [2][3]) {
int * p ;
for ( p = M [0]; p < M [0]+6; p ++)
printf ( " % d " , * p ) ;
}
main () {
int A [2][3]={{1 ,2 ,3} ,{4 ,5 ,6}};
raz ( A ) ;
afficher ( A ) ;
}

75
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les tableaux et les pointeurs
Les tableaux transmis en argument : cas des tableaux à plusieurs indices
Exemple : Somme de deux matrices : Le formalisme tableau
# include < stdio .h >
# define N 3
# define M 4
void somme ( int A [ N ][ M ] , int B [ N ][ M ] , int C [ N ][ M ])
{
int i , j ;
for ( i =0; i < N ; i ++)
for ( j =0; j < M ; j ++)
C [ i ][ j ]= A [ i ][ j ]+ B [ i ][ j ];
}
main () {
int A [ N ][ M ]={{6 ,3 ,8 ,2} ,{4 ,9 ,7 ,2} ,{5 ,3 ,6 ,1}};
int B [ N ][ M ]={{8 ,2 ,5 ,2} ,{5 ,8 ,3 ,4} ,{6 ,1 ,9 ,2}};
int C [ N ][ M ];
somme (A ,B , C ) ;
}
76
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de
recherche

77
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de recherche
Recherche sequentielle

⇒ La recherche séquentielle consiste à parcourir un tableau jusqu'à


trouver la valeur cherchée ou atteindre la n de la liste sans la trouver.
int rech_seq ( int * T , int x , int n ) {
int i ;
for ( i =0; i < n ; i ++) {
if ( T [ i ]== x ) return 1;
}
return 0;
}
main () {
int x , T []={13 ,22 ,33 ,41 ,52 ,16 ,87 ,18 ,18 ,1};
printf ( " Donner la valeur recherch é e : " ) ;
scanf ( " % d " ,& x ) ;
if ( rech_seq (T ,x ,10) ) printf ( " % d exist \ n " ,x ) ;
else printf ( " % d n ' exist pas \ n " ,x ) ;
}
78
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de recherche
Recherche dichotomique
⇒ La recherche dichotomique consiste à chercher en subdivisant le
tableau ordonnée (trié) en deux parties et vérier dans quelle partie
gurerait la valeur recherchée, puis réitérer ce processus
- Il consiste à comparer l'élément cherché avec l'élément central de
la liste (à l'indice m). Si l'élément cherché lui est inférieur, il doit se
trouver dans la première moitié sinon dans la deuxième moitié.
- Prenons un tableau trié : 1, 8, 15, 42, 99, 160, 380, 512, 678, 952,
1304. Nous cherchons dans ce tableau l'emplacement de l'élément
512 et nous allons utiliser le principe de la dichotomie pour le trouver :

79
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de recherche
Recherche dichotomique

int rech_dicho ( int * T , int x , int n ) {


int d =0 , f =n , m ;
while (d < f ) {
m =( d + f ) /2;
if ( T [ m ]== x ) return 1;
else if ( T [ m ] > x ) f = m ;
else d = m +1;
}
return 0;
}
main () {
int x , T []={1 ,13 ,16 ,18 ,18 ,22 ,33 ,41 ,52 ,87};
scanf ( " % d " ,& x ) ;
if ( rech_dicho (T ,x ,10) ) printf ( " % d exist " , x ) ;
else printf ( " % d n ' exist pas " , x ) ;
}

80
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de recherche
Tri à bulles
⇒ Le principe du tri à bulles est de comparer deux à deux les éléments
adjacents et les permuter s'ils ne sont pas dans le bon ordre. On
répète le processus jusqu'à ce qu'il n'y ait plus de permutation.
void tri_bulle ( int * T , int n ) {
int i =0 , trie , aux , l = n ;
do { | 4 | 1 | 5 | 2 | 3 |
trie =1; | 1 | 4 | 5 | 2 | 3 |
for ( i =0; i <l -1; i ++) | 1 | 4 | 5 | 2 | 3 |
if ( T [ i ] > T [ i +1]) { | 1 | 4 | 2 | 5 | 3 |
aux = T [ i ]; | 1 | 4 | 2 | 3 | 5 |
T [ i ]= T [ i +1]; | 1 | 4 | 2 | 3 | 5 |
T [ i +1]= aux ; | 1 | 2 | 4 | 3 | 5 |
trie =0; | 1 | 2 | 3 | 4 | 5 |
}
l - -;
} while ( trie ==0) ;
}
81
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de recherche
Tri à bulles

82
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les algorithmes de tri et de recherche
Tri par sélection

⇒ Le principe de par sélection est que pour classer n valeurs, il faut


rechercher la plus petite valeur et la placer au début du tableau, puis
la plus petite valeur dans les valeurs restante et la placer dans la
deuxième position et ainsi de suite.
void tri_selection ( int * T , int n ) {
int i , j , k , aux ;
| 4 | 1 | 5 | 3 | 2 |
for ( i =0; i <n -1; i ++) {
| 1 | 4 | 5 | 2 | 3 |
k=i;
| 1 | 2 | 5 | 4 | 3 |
for ( j = i +1; j < n ; j ++) {
| 1 | 2 | 3 | 4 | 5 |
if ( T [ j ] < T [ k ]) k = j ;
}
aux = T [ i ];
T [ i ]= T [ k ];
T [ k ]= aux ;
}
}
83
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères

84
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères

En langage C, il n'existe pas de véritable type chaîne comme dans


les autres langages des programmation. En revanche, il existe une
convention de représentation des chaînes utilisant des tableaux de
caractères.
Une chaîne est ainsi représentée par une suite de caractères termi-
née par un caractère supplémentaire de code nul (\0). Cela signie
qu'une chaîne de n caractères occupe en mémoire un emplacement
de n + 1 octets.

85
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
C'est cette convention qu'utilise le compilateur pour représenter les
 constantes chaîne  sous des notations de la forme :
" bonjour "
Une telle notation sera traduite par le compilateur en un pointeur
(de type char ∗) sur la zone mémoire correspondante.
Exemple :
# include < stdio .h >
main () {
char * adr ;
adr = " Bonjour " ;
while (* adr ) {
printf ( " % c " , * adr ) ;
adr ++ ;
}
}
Bonjour
86
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Tableaux de caractères

Il est possible en langage C de placer une chaîne de caractères dans


un tableau de caractères.
Exemple :
char ch [20] = " Bonjour " ;
/* Ou encore */
char ch [] = " Bonjour " ;
Cela sera parfaitement équivalent à une initialisation de ch réalisée
par une énumération de caractères (sans oublier le caractère nul de
n de chaîne (\0)) :
char ch [20]={ 'B ' , 'o ' , 'n ' , 'j ' , 'o ' , 'u ' , 'r ' , ' \0 ' };
/* Ou encore */
char ch []={ 'B ' , 'o ' , 'n ' , 'j ' , 'o ' , 'u ' , 'r ' , ' \0 ' };

87
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Tableaux de caractères

Remarque :
Comme pour les tableaux numériques, il n'est pas autorisé d'initialiser
une chaîne de caractères par une déclaration comme dans l'exemple
suivant :
char ch [20] ;
ch = " bonjour " ;
En eet, ch est une adresse constante.

88
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Tableaux de pointeurs sur des chaînes
Comme une chaîne de caractères est traduite par le compilateur en
un pointeur qui contient son adresse, il est possible de généraliser ce
principe à un tableau de pointeurs comme dans l'exemple suivant :
char * jour []={ " lundi " ," mardi " ," mercredi " ," jeudi
" ," vendredi " ," samedi " ," dimanche " };
Cette déclaration réalise donc à la fois la création des 7 chaînes
constantes correspondant aux 7 jours de la semaine et l'initialisation
du tableau jour avec les 7 adresses de ces 7 chaînes.

89
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Tableaux de pointeurs sur des chaîne

# include < stdio .h >


main () {
char * jour [7]={ " lundi " ," mardi " ," mercredi " ,"
jeudi " ," vendredi " ," samedi " ," dimanche " };
int i ;
printf ( " Donner un entier entre 1 et 7 : " ) ;
scanf ( " % d " , & i ) ;
printf ( " Le jour num é ro % d est % s " ,i , jour [i
-1]) ;
}
Donnez un entier entre 1 et 7 : 3
Le jour numéro 3 est mercredi
⇒ Remarquer le code format %s pour l'achage des chaînes de ca-
ractères.

90
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Lecture et écriture de chaînes

Le langage C ore plusieurs possibilités de lecture ou d'écriture de


chaînes :
l'utilisation du code de format %s dans les fonctions printf et
scanf ,
les fonctions spéciques de lecture gets ou d'achage puts
d'une chaîne.
Remarque :
Les fonctions printf et scanf permettent de lire ou d'acher simulta-
nément plusieurs informations de type quelconque. Par contre, gets
et puts ne traitent qu'une chaîne à la fois.

91
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Lecture et écriture de chaînes

# include < stdio .h >


main () {
char nom [20] , prenom [20] , ville [15] ;
printf ( " Quelle est votre ville : " ) ;
gets ( ville ) ;
printf ( " Donnez votre nom et votre pr é nom : " )
;
scanf ( " % s % s " , nom , prenom ) ;
printf ( " Bonjour % s %s , vous habitez à " ,
prenom , nom ) ;
puts ( ville ) ;
}
Quelle est votre ville : Mohammedia
Donnez votre nom et votre prénom : Naciri Karim
Bonjour Naciri Karim, vous habitez à Mohammedia
Remarque : Les identicateurs des tableaux n'ont pas besoin d'être
précédés par l'opérateur & puisqu'ils représentent déjà des adresses. 92
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions portant sur des chaînes

C dispose de plusieurs fonctions de manipulation de chaînes dénies


dans la bibliothèque < strig .h >.
La fonction strlen
int strlen ( char * chaine ) ;

La fonction strlen fournit en résultat la longueur d'une chaîne dont


son adresse est passée en arguments (sans compter le caractère \0).
Exemples :
strlen ( " bonjour " ) ---> 7

char * adr = " salut " ;


strlen ( adr ) ---> 5

93
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strcpy et strncpy

Les fonctions strcpy et strncpy


char * strcpy ( char * dest , char * src )

char * strncpy ( char * dest , char * src , int n )

I strcpy copie la chaîne src , y compris le caractère (\0) dans dest .


I strncpy est identique, sauf qu'au plus n octets de src sont copiés.
Remarques :
I Il faut que la chaîne dest soit assez grande pour accueillir la chaîne
src
I S'il n'y a pas de caractère nul dans les n premiers caractères de
src , la chaîne résultante dest ne disposera pas de caractère nul.

94
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strcpy et strncpy

Exemple :
# include < stdio .h >
# include < string .h >
main () {
char ch1 []= " *************** " ;
char ch2 []= " Bonjour " ;
char ch3 []= " *************** " ;
char ch4 []= " Bonjour " ;

strcpy ( ch1 , ch2 ) ;


printf ( " % s \ n " , ch1 ) ; ---> Bonjour

strncpy ( ch3 , ch4 ,3) ;


printf ( " % s \ n " , ch3 ) ; ---> Bon ************

95
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strcmp et strncmp

Les fonctions strcmp et strncmp


int strcmp ( char * s1 , char * s2 )

int strncmp ( char * s1 , char * s2 , int n )

I strcmp compare les deux chaînes s 1 et s 2 et renvoie un entier


négatif, nul, ou positif, si s 1 est respectivement inférieure, égale ou
supérieure à s 2.
I strncmp est identique à strcmp sauf qu'elle ne compare que les n
(au plus) premiers caractères de s 1 et s 2.

96
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strcmp et strncmp

Exemple :
# include < stdio .h >
# include < string .h >
main () {
char * s1 , * s2 , * s3 ;
s1 = " ABCD " ;
s2 = " EFGHIJ " ;
s3 = " ABCDEFGHIJK " ;
printf ( " % d \ n " , strcmp ( s3 , s1 ) ) ; ---> 69
printf ( " % d \ n " , strcmp ( s1 , s3 ) ) ; ---> -69
printf ( " % d \ n " , strncmp ( s1 , s3 ,4) ) ; ---> 0
printf ( " % d \ n " , strcmp ( s1 , s1 ) ) ; ---> 0
}

97
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strcat et strncat

Les fonctions strcat et strncat


char * strcat ( char * s1 , char * s2 )

char * strncat ( char * s1 , char * s2 , int n )

I strcat ajoute la chaîne src à la n de la chaîne dest en écrasant


le caractère nul (\0) à la n de dest , puis en ajoutant un nouveau
caractère nul nal. La chaîne dest doit être assez grande pour ac-
cueillir le résultat.
I strncat est similaire, à la diérence qu'elle ne prend en compte
que les n premiers caractères de src .
I strcat et strncat renvoient un pointeur sur la chaîne résultat dest .

98
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strcat et strncat

Exemple :
# include < stdio .h >
# include < string .h >
main () {
char ch1 [50] = " Bonjour " ;
char * ch2 = " Monsieur " ;
char ch3 [50] = " Bonjour " ;

strcat ( ch1 , ch2 ) ;


printf ( " % s \ n " , ch1 ) ; ---> Bonjour Monsieur

strncat ( ch3 , ch2 ,4) ;


printf ( " % s \ n " , ch3 ) ; ---> Bonjour Mon
}

99
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Les fonctions strchr et strrchr

Les fonctions strchr et strrchr


char * strchr ( char * s1 , caractere )

char * strrchr ( char * s1 , caractere )

I strchr recherche, dans chaîne, la première position où apparaît le


caractère mentionné.
I strrchr réalise le même traitement que strchr, mais en explorant
la chaîne concernée à partir de la n. Elle fournit donc la dernière
occurrence du caractère mentionné.

100
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Exercices

-Ecrire un programme C Demande à l'utilisateur de saisir son nom


puis compte les caractères et acher leur nombre
- Ecrire un programme C qui permet à un utilisateur d'entrer une
chaîne de caractères de son choix. Le programme achera par la
suite la fréquence de chaque caractère.

101
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chaînes de caractères
Solution

# include < stdio .h >


# include < stdlib .h >
# include < string .h >
int main ()
{ char text [500];
int i ,j ,x , lenght ;
printf ( " entrez votre texte \ n " ) ;
gets ( text ) ;
lenght = strlen ( text ) ;
for ( i = 'a ';i <= 'z '; i ++) {
x =0;
for ( j =0; j < lenght ; j ++) {
if ( tolower ( text [ j ]== i ) ) { x ++;
} }
if ( x !=0)
printf ( " % c ce trouve % d dans le texte \
n", i, x);
}
}
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
102
Les chaînes de caractères
Solution

# include < stdio .h >

int main () {
int nbCar ;
char tNom [30];

printf ( " Saisissez votre nom : " ) ;


scanf ( " % s " , tNom ) ;

nbCar = 0;
while ( tNom [ nbCar ] != ' \0 ') {
nbCar ++;
}

printf ( " \ nVotre nom compte % d caracteres " ,


nbCar ) ;

return 0;
}
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
103
Les structures

104
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Introduction

 Les tableaux permettent de désigner sous un seul nom un ensemble


de valeurs de même type, chacune repérée par un indice.
 Les structures permettent de désigner sous un seul nom un en-
semble de valeurs pouvant être de types diérents. L'accès à chaque
élément de la structure (nommé champ) se fera, cette fois, non plus
par une indication de position comme dans un tableau, mais par son
nom au sein de la structure.

105
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Déclaration
Exemple :
struct complexe {
float re ;
float im ;
};
 Celle-ci dénit un modèle de structure mais ne réserve pas de
variables correspondant à cette structure.
 Ce modèle s'appelle ici complexe et il précise le nom et le type de
chacun de ses "champs" (re , im).
Exemple de déclarations :
struct complexe z1 , z2 ;
Cette instruction réserve un emplacement nommé z 1 et z 2 de type
complexe.
Initialisation d'une structure :
struct complexe z = {2.3 , 5.4};
106
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Utilisation d'une structure

Il est possible d'utiliser une structure de deux manières :


en travaillant individuellement sur chacun de ses champs,
en travaillant de manière "globale" sur l'ensemble de la
structure.
 Utilisation des champs d'une structure.
⇒ Chaque champ d'une structure peut être manipulé comme n'im-
porte quelle autre variable.
⇒ La désignation d'un champ se note en faisant suivre le nom de la
variable structure de l'opérateur "point" (.) du nom de champ.
Exemple.
z1 . re = 2.3 ;
printf ( " % f " , z1 . re ) ;
scanf ( " % f " , & z1 . im ) ;
z1 . re ++ ;

107
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Utilisation d'une structure

 Utilisation globale d'une structure. Il est possible d'aecter à


une structure le contenu d'une structure dénie à partir du même
modèle.
Exemple :
struct complexe z1 , z2 ;
z1 = z2 ;
Une telle aectation globale est équivalentes à :
struct complexe z1 , z2 ;
z1 . re = z2 . re ;
z1 . im = z2 . im ;
Remarque :
L'aectation globale n'est possible que si les structures ont été dé-
nies avec le même nom de modèle.
108
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Synonymes avec typdef
L'instruction typedef permet de dénir des types synonymes et peut
s'appliquer à tous les types et non seulement aux structures.
Exemples :
typedef int entier ;
Cette déclaration signie que entier est "synonyme" de int , de sorte
que les déclarations suivantes sont équivalentes :
int n , p ; ⇔ entier n , p ;

De même pour :
typedef int * pointeur ;
signie que pointeur est synonyme de int∗. de sorte que les déclara-
tions suivantes sont équivalentes :
int * p1 , * p2 ; ⇔ pointeur p1 , p2 ;
109
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Synonymes avec typdef

En utilisant typedef , les déclarations des structures z 1 et z 2 peuvent


être réalisées comme suit :
struct nombrecomlexe {
float re ;
float im ;
} ;
typedef struct nombrecomlexe complexe ;
complexe z1 , z2 ;
Ou encore, plus simplement :
typedef struct nombrecomlexe { typedef struct {
float re ; float re ;
float im ; float im ;
} complexe ; } complexe ;
complexe z1 , z2 ; complexe z1 , z2 ;

110
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Exemple

La che de paie d'un employé comprend :


- son nom.
- nombres d'heures travaillées.
- le taux horaires.

111
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Exemple

typedef struct {
char nom [ 10 ];
int heures ;
float salaire ;
} Employe ;
Création des variables de type "structure" :
struct employe dupont ; // ( instruction qui cr é e
la variable dupont de type employe )

112
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Structure comportant des tableaux

typedef struct {
char nom [30] ;
char prenom [30] ;
float notes [5] ; /* Notes d ' un é tudiant */
int age ;
} Etudiant ;
Etudiant E1 , E2 ;
Cette déclaration réserve les emplacements pour deux structures
nommées E 1 et E 2. Ces dernières comportent trois champs :
nom qui est un tableau de 30 caractères,
pr nom qui est un tableau de 30 caractères,
notes qui est un tableau des 5 notes obtenues par l'étudiant.
age qui de type entier
Exemples d'utilisation :
E1 . notes [1]; /* deuxi è me note de E1 */
E2 . nom [4]; /* cinqi è me caract è re du nom de E2 */
113
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Tableau de structures

typedef struct {
int x ;
int y ;
} point ;
point courbe [50] ;
La structure point représente un point d'un plan et qui est déni par
ses deux coordonnées x et y .
la notation :
courbe [ i ]. x ;
désigne la valeur du champ x de l'élément de rang i du tableau
courbe.
Par ailleurs :
courbe [4] ;
représente la structure de type point correspondant au cinquième
élément du tableau courbe. 114
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Imbrication de structures

Supposons que dans les structures E 1 et E 2 dénies précédemment,


nous voulons introduire la date de naissance au lieu de l'age. Si cette
date st elle-même une structure comportant trois champs correspon-
dant au jour, au mois et à l'année, nous pouvons alors procéder
comme suit :
typedef struct {
typedef struct {
char nom [30];
int jour ;
char prenom [20];
int mois ;
date naissance ;
int annee ;
} Etudiant ;
} date ;
Etudiant E1 , E2 ;
/* Date de naissance de E1 ( de type date ) */
E1 . naissance ;
/* Ann é e de niassance de E1 ( de type int ) */
E1 . naissance . annee ;

115
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Pointeur sur une structure : l'opérateur −→

Comme pour les autres types standards, il est possible de déclarer


des pointeurs sur des structures.
point p = {3.2 , 4.5};
point * adr ;
adr = & p ;
Pour accéder aux champs de la structure d'adresse adr , l'opérateur
point (.) ne convient plus. En eet, il suppose comme premier opé-
rande un nom de structure et non une adresse.
Deux solutions s'orent :
I Adopter une notation telle que (∗adr ).x ou (∗adr ).y pour dé-
signer les champs de la structure d'adresse adr ,
I Faire appel à l'opérateur →. Ainsi, adr → x ou adr → y
désignent les champs de la structure d'adresse adr .
116
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Exemples

# include < stdio .h >


typedef struct {
float x ;
float y ;
} point ;
void deplacer ( point * p , float dx , float dy ) {
p - > x += dx ;
p - > y += dy ;
}
void afficher ( point p ) {
printf ( " (%.2 f ,%.2 f ) " ,p .x , p . y ) ;
}
main () {
point p ={4 ,7};
afficher ( p ) ; --> (4.00 ,7.00)
deplacer (& p ,2 ,5) ;
afficher ( p ) ; --> (6.00 ,12.00)
}
117
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Exemples

typedef struct {
float re ;
float im ;
} complexe ;
complexe somme ( complexe z1 , complexe z2 ) {
complexe z ;
z . re = z1 . re + z2 . re ;
z . im = z1 . im + z2 . im ;
return z ;
}
void afficher ( complexe z ) {
printf ( " %.2 f + i %.2 f " ,z . re , z . im ) ;
}
main () {
complexe c1 ={3.5 ,6.5} , c2 ={4.2 ,7.9} , c ;
c = somme ( c1 , c2 ) ;
afficher ( c ) ; --> /* 7.70 + i 14.40 */
}
118
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Exemples

# include < stdio .h >


# include < math .h >
typedef struct {
float x ;
float y ;
} vecteur ;
float norme ( vecteur v ) {
return sqrt ( v . x * v . x + v . y * v . y ) ;
}
float p_scalaire ( vecteur u , vecteur v ) {
return u . x * v . x + u . y + v . y ;
}
main () {
vecteur w ={3.3 ,5.2} , v ={5.6 ,8.4};
printf ( " %.2 f \ n " , norme ( w ) ) ; /* 6.16 */
printf ( " %.2 f \ n " , p_scalaire (v , w ) ) ; /* 32.08 */
}
119
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Exercices

- Ecrire un programme C qui dénit une structure point qui contien-


dra les deux coordonnées d'un point du plan. Puis lit deux points et
ache la distance entre ces deux derniers.

120
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Solution

# include < stdio .h >


# include < stdlib .h >
# include < math .h >

struct point {
float x ;
float y ;};
int main () {
struct point A , B ;
float dist ;
printf ( " Entrez les coordonn é es du point A :\ n " ) ;
scanf ( " % f % f " ,& A .x ,& A . y ) ;
printf ( " Entrez les coordonn é es du point B :\ n " ) ;
scanf ( " % f % f " ,& B .x ,& B . y ) ;
dist = sqrt ( ( A .x - B . x ) *( A .x - B . x ) + ( A .y - B . y ) *( A
.y - B . y ) ) ;
printf ( " La distance entre les points A et B est
: %.2 f \ n " , dist ) ;
}
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
121
Les structures
Exercices

- Dénir un type Date pour des variables formées d'un numéro de


jour, d'un nom de mois et d'un numéro d'année.
- Ecrire des fonctions de lecture et d'écriture d'une variable de type
Date. Dans un premier temps, on ne se préocupera pas de la validité
de la date entrée.

122
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Solution

# include < stdio .h >


# include < stdlib .h >

typedef struct {
int jour ;
char mois [10];
int annee ;
} DATE ;

DATE LireDate ( void ) {


DATE temp ;
printf ( " Enter la date ( format :: Day (1 -31) Month
( Janvier - Decembre ) Year ( xxxx ) ) : " ) ;
scanf ( " % d % s % d " , & temp . jour , temp . mois , & temp .
annee ) ;
return temp ;
}
123
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les structures
Solution

void AfficheDate ( DATE date ) {


printf ( " The date is : % d % s % d \ n " , date . jour ,
date . mois , date . annee ) ;
}

int main ( void ) {

DATE date ;
date = LireDate () ;
AfficheDate ( date ) ;
return 0;

124
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers

125
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers
Introduction
Un chier est un ensemble d'informations stockées sur une mémoire
de masse (disque dur, clé USB, disquette, CD-ROM, etc).
⇒ Types de chiers :
Les chiers textes : les informations sont stockées sous forme
de caractères lisibles par tout éditeur de texte.
Les chiers binaires : les informations sont stockées en binaire
et ne peuvent être lues qu'avec le logiciel adéquat (image,
vidéo, son, etc).
⇒ Modes d'accès aux chiers :
Accès séquentiel : consiste à traiter les informations
"séquentiellement", c'est-à-dire dans l'ordre où elles
apparaissent dans le chier.
Accès direct : consiste à se placer immédiatement sur
l'information souhaitée, sans avoir à parcourir celles qui la
précèdent
126
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers
Introduction

Pour utiliser un chier en C, il faut :


Ouvrir le chier en appelant la fonction fopen qui renvoie un
pointeur de type FILE*.
Vérier si l'ouverture a réussie. (le pointeur retourné est
diérent de NULL).
Accéder au chier (si l'ouverture a réussie) pour lire son
contenu et à écrire dedans.
Une fois que vous aurez ni de travailler avec le chier, il
faudra le "fermer" en appelant la fonction fclose.

127
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte
Ouverture

Syntaxe : Ouverture d'un chier texte


FILE * fopen ( char * nom , char * mode )

Cette fonction renvoie un pointeur sur le chier ouvert. Elle est dénie
dans le bibliothèque stdio.h.
nom : est une chaîne de caractères contenant le nom ou le
chemin du chier.
mode : désigne le type de traitement des données
"r" (read) : lecture (si le chier existe)
"w" (write) : écriture (le chier est crée s'il n'existe pas, sinon
il est écrasé)
"a" (append) : écriture (le chier est crée s'il n'existe pas) à la
n d'un chier existant.

128
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte
Ouverture

# include < stdio .h >


main () {
FILE * fichier ;
fichier = fopen ( " test . txt " , " w " ) ;
if ( fichier != NULL ) {
printf ( " L ' ouverture a r é ussie " ) ;
}
else {
printf ( " L ' ouverture a é chou é e " ) ;
}
}

129
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte
Fermeture

Il faut toujours fermer le chier après l'avoir utilisé an de libérer la


mémoire.
Syntaxe : Fermeture d'un chier texte
int fclose ( FILE * fichier )

Cette fonction prend en paramètre le pointeur sur le chier à


fermer.
Elle renvoie 0 si la fermeture a réussie.

130
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Ecriture dans un chier
La fonction fputc

Syntaxe : fputc pour écrire un seul caractère


fputc ( char caract è re , FILE * fichier )

# include < stdio .h >


main () {
FILE * fichier ;
fichier = fopen ( " test . txt " , " w " ) ;
if ( fichier != NULL ) {
fputc ( 'A ' , fichier ) ;
fclose ( fichier ) ;
}
else
printf ( " L ' ouverture a é chou é e .. " ) ;
}

131
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Ecriture dans un chier
La fonction fputs

Syntaxe : fputs pour écrire une chaîne


fputs ( char * chaine , FILE * fichier )

# include < stdio .h >


main () {
FILE * fichier ;
fichier = fopen ( " test . txt " , " w " ) ;
if ( fichier != NULL ) {
fputs ( " Bonjour , c ' est un test " , fichier ) ;
fclose ( fichier ) ;
}
else
printf ( " L ' ouverture a é chou é e " ) ;
}

132
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Ecriture dans un chier
La fonction fprintf

Syntaxe : fprintf pour écrire une chaîne formatée


fprintf ( FILE * fichier , char * format , expressions )

# include < stdio .h >


main () {
FILE * fichier ;
int age = 0;
fichier = fopen ( " test . txt " , " w " ) ;
if ( fichier != NULL ) {
printf ( " Quel age avez - vous ? " ) ;
scanf ( " % d " , & age ) ;
fprintf ( fichier , " vous avez % d ans " , age ) ;
fclose ( fichier ) ;
}
else
printf ( " L ' ouverture a é chou é e " ) ;
} 133
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Lecture d'un chier
La fonction fgetc

Syntaxe : fgetc pour lire un seul caractère


char fgetc ( FILE * fichier )

⇒ Renvoie EOF quand elle arrive à la n du chier.


# include < stdio .h >
main () {
FILE * fichier ;
char c ;
fichier = fopen ( " test . txt " ," r " ) ;
c = fgetc ( fichier ) ;
while ( c != EOF ) {
printf ( " % c " , c ) ;
c = fgetc ( fichier ) ;
}
fclose ( fichier ) ;
}
134
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Lecture d'un chier
La fonction fgets

Syntaxe : fgets pour lire une chaîne


char * fgets ( char * chaine , int nb_car , FILE * fich )

⇒ Renvoie NULL si la lecture a échouée.


⇒ Lit au maximum une ligne, elle sarrête au premier \n rencontré.
# include < stdio .h >
# define TAILLE_MAX 40
main () {
FILE * fichier ;
char chaine [ TAILLE_MAX ] ;
fichier = fopen ( " test . txt " , " r " ) ;
fgets ( chaine , TAILLE_MAX , fichier ) ;
printf ( " % s " , chaine ) ;
fclose ( fichier ) ;
}
135
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Lecture d'un chier
La fonction fgets

Exemple : Lire toutes les lignes.


# include < stdio .h >
# define TAILLE_MAX 100
main () {
FILE * fichier ;
char chaine [ TAILLE_MAX ]= " " ;
char * test ;
fichier = fopen ( " / Users / anter / Desktop / test .
txt " , " r " ) ;
test = fgets ( chaine , TAILLE_MAX , fichier ) ;
do {
test = fgets ( chaine , TAILLE_MAX , fichier ) ;
printf ( " % s " , chaine ) ;
} while ( test != NULL ) ;
fclose ( fichier ) ;
}

136
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte : Lecture d'un chier
La fonction fscanf

Syntaxe : fscanf pour lire une chaîne formatée


fscanf ( FILE * fichier , char * format , adresses )

⇒ Lit dans un chier qui doit être écrit d'une manière bien précise.
⇒ Lit une suite de nombres séparés par des espaces.
# include < stdio .h >
main () {
FILE * fichier ;
int a ,b , c ;
fichier = fopen ( " test . txt " , " r " ) ;
fscanf ( fichier , " % d % d % d " , &a ,& b ,& c ) ;
printf ( " % d % d % d " ,a ,b , c ) ;
fclose ( fichier ) ;
}

137
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte
Positionnement dans un chier : la fonction fseek
⇒ Les diérentes fonctions d'entrées-sorties permettent d'accéder à
un chier en mode séquentiel, autrement-dit, les données du chier
sont lues ou écrites les unes à la suite des autres.
⇒ Il est possible d'accéder à un chier en mode direct, c'est-à-dire
que l'on peut se positionner à un endroit précis du chier.
Syntaxe : La fonction seek
fseek ( FILE * fichier , long deplacement , int
origine )

La variable deplacement détermine déplacement (en nombre d'oc-


tets) par rapport à l'origine qui peut prendre trois valeurs :
SEEK_SET (égale à 0) : début du chier
SEEK_CUR (égale à 1) : position courante
SEEK_END (égale à 2) : n du chier.
138
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers texte
Positionnement dans un chier

⇒ La fonction rewind permet de se positionner au début du chier.


Syntaxe :
rewind ( FILE * fichier )
Elle est équivalente à :
fseek ( fichier , 0 , SEEK_SET )

⇒ La fonction ftellpermet de retourner la position courante dans le


chier (en nombre d'octets depuis l'origine).
Syntaxe :
long ftell ( FILE * fichier )

139
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers binaires
Ouverture

Les modes d'ouverture de chiers binaires :


"rb" (read) : lecture
"wb" (write) : écriture (le chier est écrasé s'il existe)
"ab" (append) : écriture à la n d'un chier existant

140
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers binaires
Lecture et Ecriture dans un bloc de données en binaire

Syntaxe : La fonction fwrite


fwrite ( void * source , int taille_type , int
nombre_blocs , FILE * fichier )

⇒ Ecrit un bloc de données en un seul appel


⇒ Retourne un entier, nombre d'éléments eectivement écrits
Syntaxe : La fonction fread
fread ( void * destination , int taille_type , int
nombre_blocs , FILE * fichier )

⇒ Lit un bloc de données en un seul appel


⇒ Retourne un entier, nombre d'éléments eectivement lus
141
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Les chiers binaires
Lecture et Ecriture d'un bloc de données en binaire

# define N 100
void main () {
char * src = " test . bin " ;
int i , A [ N ] , B [ N ];
FILE * fichier ;
/* Remplissage du tableau */
for ( i =1; i < N ; i ++) A [ i ]= i ;
/* Ecriture du fichier au format binaire */
fichier = fopen ( src , " wb " ) ;
fwrite (A , sizeof ( int ) ,N , fichier ) ;
fclose ( fichier ) ;
/* Lecture du fichier */
fichier = fopen ( src , " rb " ) ;
fread (B , sizeof ( int ) ,N , fichier ) ;
fclose ( fichier ) ;
/* Affichage du tableau */
for ( i =0; i < N ; i ++) printf ( " % i " ,B [ i ]) ;
}
142
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
Gestion dynamique de la
mémoire

143
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
La gestion dynamique de la mémoire

Le langage C ore les possibilités d'allocation dynamique d'espace


mémoire. Autrement-dit, les données n'ont pas non plus de taille
dénie à priori. Leur création ou leur libération dépend, des demandes
explicites faites lors de l'exécution du programme.

144
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
La gestion dynamique de la mémoire
La fonction malloc

Exemple 1 :
char * adr ;
.....
adr = ( char *) malloc (50) ;
.....
for ( p = adr ; p < adr +50 ; p ++) * p = 'a ' ;
L'appel :
malloc (50)
alloue un emplacement de 50 octets et en fournit l'adresse en retour.
Ici, cette dernière est placée dans le pointeur adr .

145
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
La gestion dynamique de la mémoire
La fonction malloc

Exemple 2 :
long * adr , * p ;
.....
adr = ( long *) malloc (100 * sizeof ( long ) ) ;
.....
for ( p = adr , i =0 ; p < adr +100 ; p ++ , i ++) * p = i ;
Cette fois, nous avons alloué une zone de 100 * sizeof(long) octets.
Toutefois, nous l'avons considérée comme une suite de 100long . Pour
ce faire, on a placé le résultat de malloc dans un pointeur sur des
éléments de type long.
p ++
correspond à l'adresse contenue dans p, augmentée de sizeof (long ).

146
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2
La gestion dynamique de la mémoire
La fonction free dénie dans <stdlib.h>
L'un des intérêts essentiels de la gestion dynamique est de pouvoir
récupérer des emplacements dont on n'a plus besoin. Le rôle de la
fonction free est de libérer un emplacement préalablement alloué.
Exemple :
# include < stdio .h >
# include < stdlib .h >
main () {
float * note ;
int N , k ;
float s =0;
printf ( " entrer le nombre de notes : " ) ;
scanf ( " % d " ,& N ) ;
note =( float *) malloc ( N * sizeof ( float ) ) ;
for ( k =0; k < N ; k ++) scanf ( " % f " , note + k ) ;
for ( k =0; k < N ; k ++) s = s +*( note + k ) ;
printf ( " somme des notes est :% f " ,s ) ;
free ( note ) ; /* Lib é ration de l 'é space m é moire */
} 147
Pr. A. OUSSOUS ahmed.oussous@fstm.ac.ma Module I132 : Algorithmique et programmation 2

Vous aimerez peut-être aussi