Voici une solution :
inline liste::~liste()// destructeur de la liste : supprime la table{ delete tab;}void liste::avance(int combien)// avance du nombre indiqué dans la liste{ if (courant) { courant += combien % nombre; combien = courant-tab; // index courant if (combien < 0) courant += nombre; else if (combien >= nombre) courant -= nombre; }}void liste::affiche(unsigned combien)// affiche combien éléments de la liste// (et nombre_elt au max){ if (combien > nombre) combien = nombre; element *fin = tab +nombre; while (combien--) { cout << '\t' << *courant; if (++courant == fin) courant = tab; } cout << '\n';}liste::liste(int n, const element* etab)// construit une liste de n éléments pointés par etab{ nombre = 0; courant = tab = 0; if ( (n <= 0) || (!etab) ) return; if (!(tab = new element[n])) return; memmove(tab, etab, n*sizeof(element) ); nombre = n; courant = tab;}int liste::insere(const element& e)// insère e à la position courante; // renvoie 0 si plus de place{ unsigned size = sizeof(element); element *ep = (element*) realloc(tab, (1+nombre)*size ); if (!ep) return 0; // plus de place mémoire int i = courant -tab; // index actuel tab = ep; courant = tab +i; memmove(courant+1, courant, (nombre++ -i)*size); *courant = e; return 1;}void liste::supprime(int n)// supprimer le nombre indiqué d'éléments de la liste{ if (n <= 0) return; if (n >= nombre) { nombre = 0; courant = tab = 0; return; } nombre -= n; // nouvelle taille int i = courant -tab, queue = nombre -i; // ce qui reste en fin unsigned size = sizeof(element); if (queue > 0) // ramener les derniers memmove(courant, courant+n, queue*size); else if (queue < 0) // supprimer les premiers en trop memmove(tab, tab-queue, nombre*size); tab = (element*) realloc(tab, nombre*size); // plus petit donc toujours ok en principe if (queue > 0) courant = tab +i; else courant = tab;}
On notera que les opérations de suppression et dinsertion sont plus complexes, mais que les autres sont plus simples. Dautre part, le constructeur a un effet légèrement différent de celui de la première version, en ce sens que si la place mémoire manque, il crée une liste vide, alors que lautre remplissait partiellement la liste jusquà débordement.