Vous êtes sur la page 1sur 55

Chapitre 3

Structures de Données Linéaires :


Les Listes

PREMIERE PARTIE

1
Listes

◼ Une liste est une structure linéaire


particulièrement souple : elle peut grandir ou
rétrécir à volonté, et ses éléments, peuvent
être insérés ou supprimés à n’importe quel
endroit.
◼ D’un point de vue mathématique, une liste est
une suite, vide ou non, d’éléments d’un type
donné
◼ listes homogènes :
◼ tous les éléments sont du même type

◼ listes hétérogènes :
◼ les éléments sont de types différents

◼ dans la suite nous nous intéressons aux


listes homogènes

2
Principes des TDA

◼ se placer à un niveau d'abstraction élevé


◼ éviter les erreurs de conception

◼ programmer avec des opérations de haut niveau


◼ qui ne dépendent pas de la représentation interne

◼ qui permettent de changer de représentation

◼ qui permettent à l'utilisateur de se concentrer sur

les problèmes de conception en ignorant les détails


de réalisation
◼ encapsuler les données
◼ n'accéder à la représentation interne que via des

fonctions
◼ l'utilisateur ne voit que les services (l’interface) pas

la représentation interne

3
Les types de données
abstraits (TDA)

◼ définition :
◼ un ensemble de données organisé pour que les

spécifications des objets et des opérations sur


ces objets soient séparées de la représentation
interne des objets et de la mise en œuvre des
opérations

◼ nés de préoccupation de génie logiciel


◼ abstraction

◼ encapsulation

◼ vérification de types

4
Incarnation d'un TDA

◼ définition :
une incarnation (une réalisation, une mise en œuvre,
une « implémentation ») d'un TDA est
◼ la déclaration de la structure de données

particulière retenue pour représenter le TDA


◼ L’interface (fichier .h)

◼ et la définition (i.e le code) des opérations

primitives dans un langage particulier


◼ La réalisation (fichier .c)

◼ on parle aussi de type concret de données

5
Les éléments d’une
liste:

◼ Les éléments de la liste sont


déclarés de type ELEMENT
permettant ainsi de définir une
liste générique.
◼ On distingue alors les éléments à
stockage
◼ direct
◼ indirect

6
Stockage direct
◼ Définition
◼ Un conteneur est en stockage direct quand il

contient les objets


◼ Exemples
◼ liste d’entiers l = (1 2 3 4 )

◼ Utilisation
◼ « Petits objets » en mémoire et facile à copier

◼ Nombres, caractères, éventuellement des structures

avec des champs simples


◼ Allocation/Libération des objets contenus
◼ Un conteneur en stockage direct est propriétaire des

objets qu’il contient cad ses objets sont alloués et


libérés de façon automatique en même temps que le
conteneur

7
Stockage indirect
◼ Définition
◼ Un conteneur est en stockage indirect quand il

contient des pointeurs sur des objets (cad


l’adresse des objets stockés)
◼ Exemples
◼ liste de chaînes de caractères, listes de

pointeurs sur des structures, listes de listes


◼ Utilisation
◼ Gros objets, objets avec des champs

dynamiques, objets partagés par plusieurs


conteneurs
◼ Allocation/libération des objets contenus
◼ Un conteneur en stockage indirect n’est pas

propriétaire des objets qu’il contient i.e. il n’est


pas responsable de l’allocation/libération des
objets pointés
◼ En C, c’est la responsabilité du programmeur

de libérer la mémoire allouée dynamiquement


◼ Une difficulté du C

8
TDA ELEMENT
◼ tous les éléments appartiennent à un TDA ELEMENT
qui possède un élément vide et sur lequel on peut :

◼ saisir un élément
◼ afficher un élément
◼ affecter un élément dans un autre élément
◼ copier les informations d’un élément dans un autre
élément (le dupliquer)
◼ comparer deux éléments
◼ allouer dynamiquement la mémoire ou initialiser un
élément
◼ libérer la mémoire allouée pour un élément

◼ On va créer un header (ELTPRIM.H)

9
TDA ELEMENT
/***************************************************
* Fichier : ELTPRIM.H
* Contenu : Déclaration des primitives du TDA ELEMENT.
***************************************************/

#ifndef _ELTPRIM_H
#define _ELTPRIM_H

#include "ELTSDD.H"

/* Lecture d'un élément*/


void elementLire(ELEMENT *);

/* Affichage d'un élément/


void elementAfficher(ELEMENT);

/* Affectation du 2eme argument dans le 1er qui est donc modifié et passé par
adresse */
void elementAffecter(ELEMENT*, ELEMENT);

/* Copie du contenu du deuxième argument dans le premier, les deux


arguments ont des adresses différentes (duplication)*/
void elementCopier(ELEMENT *, ELEMENT) ;

/* Comparaison des arguments retourne un entier 0, < 0 ou > 0 la


"différence" (e1-e2) */
int elementComparer(ELEMENT, ELEMENT);

/* Création d'un élément*/


ELEMENT elementCreer(void) ;

/* Libération de mémoire */
void elementDetruire (ELEMENT);
#endif 10
Remarque

◼ Les deux primitives elementAffecter et


elementCopier sont utiles dans le cas du
stockage indirect (la première permet de
pointer sur le même élément alors que la
seconde permet de changer les valeurs) -
Voir exemple (suite)
◼ Dans le cas du stockage direct ces deux
primitives sont identiques

11
Exemple 1: stockage
direct (entiers) (1)

La définition est faite dans le ELTINT.h

/***************************************************
* Fichier : ELTINT.H
* Contenu : Déclaration de la structure de données adoptée
* pour une réalisation du TDA ELEMENT.
***************************************************/

#ifndef _ELTINT_H
#define _ELTINT_H

typedef int ELEMENT;

#endif

12
Exemple 1: stockage
direct (entiers) (2)
/********************************************************
* Fichier : ELTINT.C
* Contenu : Définition des primitives pour une réalisation par des
entiers du TDA ELEMENT.
********************************************************/
#include <stdio.h>
#include "ELTPRIM.H" ELEMENT est
définit dans
#define ELEMENT_VIDE 32767
ELTINT.H qui est
reconnu
ELEMENT elementCreer (void) { automatiquement
return ELEMENT_VIDE ;} dans ELTINT.C

void elementDetruire (ELEMENT elt) {


/* ne fait rien en stockage direct*/

Dans le stockage direct les opérations de création et


de libération sont simplifiées il n’y a ni allocation ni
libération de la mémoire

13
Exemple 1: stockage
direct (entiers) (3)

void elementAffecter(ELEMENT * e1, ELEMENT e2) {


*e1 = e2 ;}

void elementCopier(ELEMENT * e1, ELEMENT e2) {


*e1 = e2 ;}

Dans le stockage direct elementAffecter et elementCopier


sont identiques

14
Exemple 1: stockage
direct (entiers) (4)

void elementLire(ELEMENT * elt) {


printf(« \nun entier svp :") ;
scanf("%d",elt);
}

void elementAfficher(ELEMENT elt) {


printf(" %d ",elt);
}

int elementComparer(ELEMENT e1, ELEMENT e2)


{
return (e1-e2);
}

15
Exemple 2: stockage
indirect (client) (1)
Le client est une structure :
➢ Nom
➢ Adresse
➢ cin

/*****************************************************
* Fichier : ELTCLT.H
* Contenu : Déclaration de la structure de données adoptée
* pour une réalisation du TDA ELEMENT par client.
*****************************************************/

#ifndef _ELTCLT_H
#define _ELTCLT_H

typedef struct
{
char nom[20];
char adresse[30];
int cin;
ELEMENT ici est un
} elem, *ELEMENT; pointeur sur une
structure
#endif

16
Exemple 2: stockage
indirect (client) (2)
/*************************************************
* Fichier : ELTCLT.C
* Contenu : Définition des primitives pour une réalisation par
des clients du TDA ELEMENT.
************************************************/

#include <stdio.h>
Ici on utilise malloc
#include <stdlib.h> et free car on est
#include <string.h> dans le stockage
#include "ELTPRIM.H" indirect (pointeurs)

#define ELEMENT_VIDE NULL

ELEMENT elementCreer (void) {


ELEMENT L;
L = (ELEMENT) malloc(sizeof(elem));
return L;
}
Sizeof(elem) est
void elementDetruire (ELEMENT elt) { different de
free (elt); sizeof(ELEMENT))
}

17
Exemple 2: stockage
indirect (client) (3)
void elementLire(ELEMENT* elt) {
char x;
printf(" \nDonnez un nom svp :") ;
fgets((*elt)->nom, 18, stdin);
printf(" \nDonnez une adresse svp :") ;
fgets((*elt)->adresse, 18,stdin);
printf(" \nDonnez le numéro CIN :") ;
scanf("%d",&((*elt)->cin));
x=getchar();
}

void elementAfficher(ELEMENT elt) {


printf(«\nnom = %s , adresse = %s , CIN= %d ",elt-
>nom, elt->adresse, elt->cin);
}

18
Exemple 2: stockage
indirect (client) (4)
void elementAffecter(ELEMENT* e1, ELEMENT e2) {
*e1 = e2 ;
}
e1 @ cl1 ◼ e1: contient une adresse d’un client
ali ◼ *e1 est égal à @cl1
@ cl1 adr1 ◼ (*e1)->nom est égal à ali
10 ◼ (*e1)->adresse est égal à adr1
◼ (*e1)->cin est égal à 10
e2 ◼ e2: est une adresse d’un client
hamed ◼ e2->nom est égal à hamed
adr2 ◼ e2->adresse est égal à adr2
20 ◼ e2->cin est égal à 20
elementAffecter(&e1, e2)
e1 @ cl1 ◼ e1: contient une adresse d’un client
e2 ali ◼ *e1 est égal à e2
adr1 ◼ (*e1)->nom est égal à hamed
10 ◼ (*e1)->adresse est égal à adr2
◼ (*e1)->cin est égal à 20
e2
hamed
adr2
20 19
Exemple 2: stockage
indirect (client) (5)
int elementCopier(ELEMENT *e1, ELEMENT e2) {
strcpy((*e1)->nom, e2->nom);
strcpy((*e1)->adresse, e2->adresse);
(*e1)->cin = e2->cin;
}

e1 @ cl1 e1 @ cl1
ali hamed
@ cl1 adr1 @ cl1 adr2
10 20

e2 e2
hamed hamed
adr2 adr2
20 20

elementCopier(&e1, e2)

Remarque : (**e1).cin est equivalent à (*e1)->cin


(*e2).cin est equivalent à e2->cin
20
Exemple 2: stockage
indirect (client) (6)

int elementComparer(ELEMENT e1, ELEMENT e2) {


return ((e1->cin) – (e2->cin)) ;
}

21
Remarque
◼ Afin d’établir le lien entre ELTPRIM.H et les
implémentations on utilise un fichier intermédiaire
ELTSDD.H qui va définir le fichier d’implémentation
◼ ELTSDD.H sera modifié quand on voudra changer la
représentation adoptée (entier, clients etc.)

/******************************************************
* Fichier : ELTSDD.H
* Contenu : Inclusion du fichier où est déclarée la structure
de données adoptée pour réaliser le TDA ELEMENT.
******************************************************/

#ifndef _ELTSDD_H
#define _ELTSDD_H

#include "ELTCLT.H"
ou
ELTINT.H
#endif

22
/* ELTSDD.h sera modifié
quand on voudra changer la
Schéma général
représentation adoptée
(entier string etc.)*/
ELTSDD.h
ou

include

ELTPRIM.h

entiers …

ELTINT.h ….

ELTINT.c ….

23
L’implantation des
listes en C

◼ TDA indépendant de son


implémentation: donc on peut
proposer plusieurs
implémentations différentes:
◼ Listes contiguës (en utilisant

un tableau)
◼ Listes chaînées

24
Primitives du TDA
LISTE
/*****************************************************************
* Fichier : LSTPRIM.H
* Contenu : Déclaration des primitives du TDA LISTE
******************************************************************/
#ifndef _LSTPRIM_H
#define _LSTPRIM_H
Toutes les
#include "ELTPRIM.H"
primitives des
#include "LSTSDD.H"
éléments
peuvent êtres
LISTE listeCreer(void);
utilisées
void listeDetruire(LISTE);
int estVide(LISTE);
int estSaturee(LISTE);
int listeTaille(LISTE);
ELEMENT recuperer(LISTE, int);
int inserer(LISTE, ELEMENT,int);
int supprimer(LISTE, int);
void listeAfficher(LISTE);
LISTE listeCopier(LISTE);
int listeComparer(LISTE, LISTE);

#endif

25
Implémentation
contiguë

◼ Les éléments de la liste sont


mémorisés dans les cellules
contiguës d’un tableau.
◼ Dans ce cas, une liste est
caractérisée par:
◼ une taille physique
◼ une taille logique (lg)

26
Implémentation
contiguë (en C)
◼ une liste contiguë est un pointeur sur
une structure à deux champs
◼ un tableau qui contient les éléments de la liste
(éléments) : la première case est vide afin
d’éviter le décalage entre les positions et les
indices
◼ un entier indiquant l'indice du dernier élément de
la liste (lg) =taille logique

L éléments 0 %

1 a
2 b
3 c
...
100 @

lg 3
27
Exemple: liste en
stockage direct
◼ Liste d’entiers
◼ Chaque case de la liste contient un entier

L éléments 0 %

1 123

2 34

3 5
4 67
...
...
100 @

lg 4

28
Exemple: liste en
stockage indirect
◼ Liste de clients
◼ Chaque case de la liste contient l’adresse
d’une structure client (pointe sur un client)

L ali
éléments 0 %
@ cl1 adr1
1 @ cl1 10
2 @ cl2 hamed
@ cl3 @ cl2 adr2
3
@ cl4 20
4
salah
...
@ cl3 adr3
...
30
100 @
karim
lg 4 @ cl4 adr4
40
29
Déclaration de la
structure

/***************************************************
* Fichier : LSTTAB.H
* Contenu : Déclaration de la strucure de données pour réaliser
* le TDA LISTE PAR TABLEAU
***************************************************/

#ifndef _LSTTAB_H
#define _LSTTAB_H

#include "ELTPRIM.H"

#define LongMax 100 /* longueur maximale d'une liste */

typedef struct {
ELEMENT elements[LongMax]; /* tableau automatique */
int lg; /* taille logique de la liste */
} laStruct,*LISTE;

#endif

30
Remarques

◼ La mise en œuvre par tableau facilite les parcours de


listes indexées et l’insertion d’éléments en fin de liste.
◼ En revanche, l’insertion d’un élément au milieu d’une
liste nécessite de déplacer tous les éléments suivants
dans le tableau pour créer la place nécessaire au
nouveau venu.
◼ De même, la suppression d’un élément quelconque
du tableau demande que l’on déplace tous ses
successeurs pour "boucher le trou" produit, sauf
lorsqu’il s’agit du dernier élément de la liste.

31
Implémentation des
primitives
/******************************************************
* Fichier : LISTAB.C
* Contenu : Définition des primitives pour une réalisation
* par tableau du TDA LISTE.
******************************************************/

#include <stdlib.h>
#include <stdio.h>
#include "LSTPRIM.H"

LISTE listeCreer(void) {
LISTE L;
L = (LISTE) malloc(sizeof(laStruct));
if(!L) {
printf(" \nProblème de mémoire") ;
exit(0) ;
}
L->lg = 0;
return(L);
}

void listeDetruire(LISTE L){


int i;
for(i = 1;i <= L->lg; i++)
elementDetruire(L->elements[i]);

free(L);
} 32
Insertion
int inserer (LISTE L, ELEMENT e, int pos) {
int i;
int succee=1;

if (estSaturee(L)){
printf ("\nListe saturée");
succee=0;}
else {
if ((pos < 1) || (pos > L->lg + 1)) {
printf ("\nPosition invalide");
succee=0;
}
else {
for(i = L->lg; i>= pos; i--)
elementAffecter(&L->elements[i+1],
L->elements[i]);

elementAffecter(&L->elements[pos], e);
(L->lg)++;
}
}
return(succee);

} 33
Exemple Insertion
(stockage direct)
Insérer (77) à la position 2

L éléments 0 %

1 123

2 34

3 5
4 67
...
...

100 @

lg 4

34
Exemple Insertion
(stockage direct)
Insérer (77) à la position 2

elementAffecter(&L->elements[5], L->elements[4]);

L éléments 0 %

1 123

2 34

3 5
4 67
5 67
...

100 @

lg 4

35
Exemple Insertion
(stockage direct)
Insérer (77) à la position 2

elementAffecter(&L->elements[4], L->elements[3]);

L éléments 0 %

1 123

2 34

3 5
4 5
5 67
...

100 @

lg 4

36
Exemple Insertion
(stockage direct)
Insérer (77) à la position 2

elementAffecter(&L->elements[3], L->elements[2]);

L éléments 0 %

1 123

2 34

3 34
4 5
5 67
...

100 @

lg 5

37
Exemple Insertion
(stockage direct)
Insérer (77) à la position 2

elementAffecter(&L->elements[2], 77);
(L->lg)++;

L éléments 0 %

1 123

2 77

3 34
4 5
5 67
...

100 @

lg 5

38
Exemple Insertion
(stockage indirect)

Insérer (saber, adr5, 50) qui est à l’adresse @ cl5 à la position 2

L ali
éléments 0 % @ cl1 adr1
10
1 @ cl1
hamed
2 @ cl2
@ cl2 adr2
3 @ cl3 20
4 @ cl4 salah
... @ cl3 adr3
... 30

100 @ karim
@ cl4 adr4
lg 4 40
saber
@ cl5 adr5
50 39
Exemple Insertion
(stockage indirect)
Insérer (saber, adr5, 50) à la position 2
elementAffecter(&L->elements[5], L->elements[4]);
la 5eme case du tableau reçoit @ cl4 (pointe sur le client à l’adresse @ cl4)

L ali
éléments 0 % @ cl1 adr1
10
1 @ cl1
hamed
2 @ cl2
@ cl2 adr2
3 @ cl3 20
4 @ cl4 salah
5 @ cl4 @ cl3 adr3
... 30

100 @ karim
@ cl4 adr4
lg 4 40
saber
@ cl5 adr5
50 40
Exemple Insertion
(stockage indirect)
Insérer (saber, adr5, 50) à la position 2
elementAffecter(&L->elements[4], L->elements[3]);
la 4eme case du tableau reçoit @ cl3 (pointe sur le client à l’adresse @ cl3)

L ali
éléments 0 % @ cl1 adr1
10
1 @ cl1
hamed
2 @ cl2
@ cl2 adr2
3 @ cl3 20
4 @ cl3 salah
5 @ cl4 @ cl3 adr3
... 30

100 @ karim
@ cl4 adr4
lg 4 40
saber
@ cl5 adr5
50 41
Exemple Insertion
(stockage indirect)
Insérer (saber, adr5, 50) à la position 2
elementAffecter(&L->elements[3], L->elements[2]);
la 3eme case du tableau reçoit @ cl2 (pointe sur le client à l’adresse @ cl2)

L ali
éléments 0 % @ cl1 adr1
10
1 @ cl1
hamed
2 @ cl2
@ cl2 adr2
3 @ cl2 20
4 @ cl3 salah
5 @ cl4 @ cl3 adr3
... 30

100 @ karim
@ cl4 adr4
lg 4 40
saber
@ cl5 adr5
50 42
Exemple Insertion
(stockage indirect)
Insérer (saber, adr5, 50) à la position 2
elementAffecter(&L->elements[2], @ cl5 );
la 3eme case du tableau reçoit @ cl5 (pointe sur le client à l’adresse @ cl5)
(L->lg)++;
L ali
éléments 0 % @ cl1 adr1
10
1 @ cl1
hamed
2 @ cl5
@ cl2 adr2
3 @ cl2 20
4 @ cl3 salah
5 @ cl4 @ cl3 adr3
... 30

100 @ karim
@ cl4 adr4
lg 5 40
saber
@ cl5 adr5
50 43
Suppression

int supprimer (LISTE L, int pos ) {


int i;
int succee=1;

if (estVide(L)) {
printf ("\nListe vide");
succee=0;}
else {
if ((pos < 1) || (pos > L->lg)) {
printf (“\nPosition invalide");
succee=0;}
else {
elementDetruire(L->elements[pos]);
for(i=pos;i<=L->lg;i++)
elementAffecter(&L->elements[i],
L->elements[i+1]);
(L->lg)--;
}
}
return(succee);
}

44
Récupérer
ELEMENT recuperer(LISTE L, int pos) {

ELEMENT elt= elementCreer();


if (estVide(L))
printf (« \nListe vide");
else {
if ((pos < 1) || (pos > L->lg))
printf (« \nPosition invalide");
else
elt=(L->elements[pos]);
}
return(elt);
}

◼ s'il y a une erreur on affiche un message et on retourne un


élément vide
◼ dans le cas de stockage indirect récupérer retourne un pointeur
sur l'élément et non une copie de cet élément cad si on modifie
les champ pointés par le résultat on modifie directement la liste
◼ Exemple:
◼ elt=recuperer(L,2)
◼ elt->cin=0
◼ Le cin du client à la position 2 devient 0 45
Copier (1)

LISTE listeCopier(LISTE L){

LISTE LR = listeCreer();

int i;
ELEMENT elt;

for(i = 1;i <= L->lg; i++) {


elt=elementCreer();
elementCopier(&elt, recuperer(L,i));
inserer(LR, elt, i);
}
return LR;
}

46
Copier (2)
Si on utilise elementAffecter au lieu de elementCopier
alors pour les listes qui contiennent des éléments en
stockage indirect on aura:
L LR
@ cl1
éléments ali éléments
adr1
0 % % 0
10
1 @ cl1 @ cl1 1
@ cl2 @ cl2 @ cl2
2 2
hamed
3 @ cl3 @ cl3 3
adr2
4 @ cl4 20 @ cl4 4
... ...
@ cl3
... ...
salah
100 @ adr3 @ 100
30
lg 4 4 lg
@ cl4
karim
adr4
40 47
Comparaison

int listeComparer (LISTE L1,LISTE L2 )


{
int test= 1;
int i=1;

if (listeTaille(L1) != listeTaille(L2)) test= 0;

while ((i<=listeTaille(L1)) && (test)) {


if (elementComparer(recuperer(L1,i),recuperer(L2,i))!=0)
test=0;
i++;
}

return test;
}

Retourne 1 si les listes sont égales et 0 sinon

48
listeAfficher, estVide,
estSaturee, listeTaille
void listeAfficher(LISTE L) {
int i;
for(i = 1; i <= L->lg; i++)
elementAfficher(L->elements[i]);
}

int estVide(LISTE L) {
return (L->lg == 0);
}

int estSaturee(LISTE L) {
return (L->lg == LongMax);
}

int listeTaille(LISTE L) {
return (L->lg);
}

49
Remarque
◼ Afin d’établir le lien entre LSTPRIM.H et les
implémentations on utilise un fichier intermédiaire
LSTSDD.H qui va définir le fichier d’implémentation
◼ LSTSDD.H sera modifié quand on voudra changer la
représentation adoptée (chaînée, contiguë etc.)

/************************************************
* Fichier : LSTSDD.H
* Contenu : Inclusion du fichier où est déclarée la structure
* de données adoptée pour réaliser le TDA LISTE.
************************************************/

#ifndef _LSTSDD_H
#define _LSTSDD_H

#include "LSTTAB.H"

#endif
Ou
LSTPTR.H
50
/* LSTSDD.h
Schéma général
sera modifié quand on voudra
changer la représentation
adoptée (chainée- contigue
etc.)*/
LSTSDD.h
ou

include

LSTPRIM.h

contiguë chainée

LSTTAB.h LSTPTR.h
(structure) (structure)

ELTPRIM.h

….
LSTTAB.c LSTPTR.c

51
L’utilisation: exemple
/********************************************
* Fichier : main.c
* Contenu : Test du TDA LISTE
********************************************/
#include <stdio.h>
#include "ELTPRIM.H"
#include "LSTPRIM.H"

int main()
{
int i;
ELEMENT elt;
LISTE L = listeCreer();

printf ("\nEntrez une liste de 4 entiers svp : \n") ;


for (i = 0; i < 4; i++) {
ElementLire(&elt) ;
inserer(elt, i+1, L);
}
listeAfficher(L);
listeDetruire(L);
return 0 ;
}
52
Création du projet
sous Visual C++

53
Création du projet
sous Visual C++

◼ Dans cet exemple on utilise une implémentation


contiguë des listes d’entiers
◼ A chaque fois qu’on veut changer d’implémentation
ou de type d’éléments il suffit de changer les fichiers
du projet (ou créer un autre projet)

54
Remarques
◼ C++, JAVA, ADA sont conçus pour supporter la
réalisation de TDA
◼ en C comme vous avez constaté, utiliser les TDA
c'est assez acrobatique et même contre nature
◼ pourquoi le langage C ?
◼ le plus répandu
◼ impensable encore de se dire informaticien en
sans maîtriser le C
◼ mettre en œuvre les TDA en C vous permettra
de maîtriser le C mais aussi de mieux
comprendre les problèmes résolus par C++ (ou
java) et d'accepter de payer le prix de la
complexité technique des langages orientés
objets pour obtenir une plus grande sécurité de
programmation.

55

Vous aimerez peut-être aussi