Gestionnaire de listes
- typedef struct _list {
- int l;
- void **v;
- } *list;
Un type list
est constitué d'une simple suite consécutive de pointeurs. l
donne le nombre d'éléments dans la liste. v
pointe sur une zone en mémoire assez grande pour contenir tous les éléments de la liste.
- extern list list_alloc( void );
- extern list list_init( list this );
- extern list list_new( void );
- extern void list_free( list this );
- extern int list_length( list this );
- extern void *list_get( list this, int key );
- extern void *list_put( list this, int key, void *val );
- extern void *list_delete( list this, int key );
- extern void *list_insert( list this, int key, void *val );
list_new
retourne une nouvelle liste vide.
list_free
désalloue la mémoire occupée par une liste.
list_length
donne le nombre d'éléments contenus dans une liste.
list_get
retourne un élément d'une liste.
list_put
, list_insert
et list_delete
modifient le contenu d'une liste.
- list list_alloc( void ) {
- return (list)calloc( 1, sizeof ( struct _list ));
- }
- list list_init( list this ) {
- return this;
- }
- list list_new( void ) {
- return list_init( list_alloc() );
- }
- void list_free( list this ) {
- if ( this->v )
- free( this->v );
- free( this );
- }
list_new
retourne une instance de list
nouvellement allouée et initialisée.
list_alloc
alloue la mémoire nécessaire à une liste et la retourne.
list_init
retourne la liste this
après l'avoir initialisée.
list_free
libère la mémoire occupée par le tableau de pointeurs et la structure de la liste this
.
- int list_length( list this ) {
- return this->l;
- }
list_length
retourne le nombre d'éléments de la liste this
.
- void *list_get( list this, int key ) {
- if ( key < 0 )
- return this->l ? this->v[ this->l - 1 ] : 0;
- else if ( key < this->l )
- return this->v[ key ];
- else
- return 0;
- }
list_get
retourne l'élément de la liste this
à la position key
.
Si key
est négatif, list_get
retourne le dernier élément de la liste.
Si la liste est vide ou si key
est supérieur à la longueur de la liste, list_get
retourne 0.
- void *list_put( list this, int key, void *val ) {
- if ( key < 0 )
- key = this->l;
- if ( key < this->l )
- this->v[ key ] = val;
- else {
- this->l = key + 1;
- this->v = (void **)realloc( this->v, (key + 1) * sizeof ( void * ));
- this->v[ key ] = val;
- }
- return val;
- }
list_put
place val
à la position key
dans la liste this
. val
est un pointeur quelconque.
Si key
est négatif, val
est ajouté à la fin de la liste.
Si la liste est vide ou si key
est supérieur à la longueur de la liste, list_put
alloue assez d'espace pour contenir key
éléments et place val
à la fin de la liste.
NOTE : realloc
prend soin de copier les données si un nouveau bloc de mémoire est effectivement alloué.
list_put
retourne val
.
- void *list_delete( list this, int key ) {
- void **p, *val;
- if ( key < 0 )
- key = this->l ? this->l - 1 : 0;
- if ( key < this->l ) {
- val = this->v[ key ];
- this->l--;
- for ( p = this->v + key; p < this->v + this->l; p++ )
- *p = *(p+1);
- return val;
- }
- else
- return 0;
- }
list_delete
supprime l'élément de la liste this
à la position key
.
Si key
est négatif, list_delete
supprime le dernier élément de la liste.
list_delete
décrémente la longueur de la liste et décale tous les éléments de la liste vers la gauche à partir de key
+ 1. Tous les éléments après key
changent d'index.
list_delete
retourne l'élément supprimé ou 0 si la liste est vide ou si key
est supérieur à la longueur de la liste.
- void *list_insert( list this, int key, void *val ) {
- void **p;
- if ( key < 0 || key >= this->l )
- return list_put( this, key, val );
- this->l++;
- this->v = (void **)realloc( this->v, this->l * sizeof ( void * ));
- for ( p = this->v + (this->l - 1); p > this->v + key; p-- )
- *p = *(p-1);
- this->v[ key ] = val;
- return val;
- }
list_insert
insère l'élément val
à la position key
dans la liste this
. val
Si key
est négatif ou supérieur à la longueur de la liste, val
est ajouté à la fin de la liste.
list_insert
incrémente la longueur de la liste, alloue assez d'espace pour contenir un élément de plus, décale tous les éléments de la liste vers la droite à partir de key
+ 1 et place val
à la position key
. Tous les éléments après key
changent d'index. NOTE : realloc
prend soin de copier les données si un nouveau bloc de mémoire est effectivement alloué.
list_insert
retourne l'élément ajouté.
Commentaires