EXERCICE 1 ========== (1) a=9 *p=9 (2) a=9 *p=9 (3) a=9 *p=9 (4) a=10 *p=10 (5) a=10 *p=10 Une erreur d'execution aura lieu apres la point d'observation (5) car on va acceder au tableau t en dehors de ces bornes (case d'indice 10). EXERCICE 2 ========== // Q2 // on definit un Triplet contenant un element entier, // un pointeur sur le Triplet suivant et un pointeur // sur le Triplet precedent typedef struct triplet { int element ; struct triplet *prec ; // precedent struct triplet *suiv ; // suivant } Triplet ; // une liste doublement chainee est un pointeur sur Triplet ... typedef Triplet * Liste_Double_Chainee ; EXERCICE 3 ========== // Q1 #define ADMAX 1024 typedef int adresse ; // defini sur -1..ADMAX adresse Mem[ADMAX-1] ; void init() ; int estLibre (adresse ad) ; int tailleBloc (adresse ad) ; adresse premBloc() ; adresse blocSuiv (adresse ad) ; int nbLibre() ; /* --------------------------------------- */ // Q2 int nbLibre() { adresse adcour ; // adresse courante int compteur = 0 ; // nbre de blocs libres adcour = premBloc() ; while (adcour != -1) { if (estLibre(adcour)) compteur = compteur +1 ; adcour = blocSuiv(adcour) ; // acces au bloc suivant } return compteur ; } /* --------------------------------------- */ // Q3 void init() { Mem[1] = ADMAX -1 ; // un seul bloc libre de taille ADMAX-1 } /* --------------------------------------- */ // Q4 int estLibre (adresse ad) { return Mem[ad -1] > 0 ; } int tailleBloc (adresse ad) { return abs (Mem[ad -1]) ; // abs est la fonction valeur absolue } adresse premBloc() { return 1 ; // le premier bloc a pour adresse 1 } adresse blocSuiv (adresse ad) { return ad + tailleBloc(ad) + 1 ; } /* --------------------------------------- */ // Q5 int main() { Mem[0] = -3 ; Mem[4] = 2 ; Mem[7] = -1016 ; return 0 ; } /* --------------------------------------- */ // Q6 void Reallouer (adresse *ad, int t) { int tmp ; // adresse temporaire int i ; Allouer (t, &tmp) ; // on alloue un bloc de taille t a l'adresse temp if (tmp != -1) { for (i=0 ; i= t if (adcour !=1 ) { // ce bloc existe taille = tailleBloc(adcour) ; // taille du bloc dans lequel on alloue Mem[adcour -1] = t ; // on fixe la taille du bloc alloue if (taille > t+1) // on peut creer un nouveau bloc avec le morceau restant Mem[adcour + t] = - (taille -t) ; // on fixe la taille de ce nouveau bloc // Remarque // on aurait aussi pu fusionner ce nouveau bloc avec le bloc suivant s'il etait libre // (mais ce n'etait pas demande ...) } else { *ad = - 1 ; } } /* --------------------------------------- */ // Q9 void Liberer (adresse ad) { adresse adsuiv ; // adresse du bloc suivant adsuiv = blocSuiv(ad) ; if (adsuiv != -1 && estLibre(adsuiv)) // le bloc suivant est libre, on le fusionne avec le bloc d'adresse ad Mem[ad-1] = tailleBloc(ad) + tailleBloc(adsuiv) ; else Mem[ad-1] = - tailleBloc(ad) ; // on change le signe de la taille du bloc } /* ------------------------------------------ */ // Q10 /* Popur fusionner un bloc b avec le bloc precedent il faut pouvoir acceder au bloc precedent ... Pour cela il y a (au moins) 2 solutions : - soit reparcourir la liste des blocs depuis le premier bloc pour trouver l'adresse du bloc precedent le bloc b ; - soit modifier la structure du tableau Mem pour memoriser pour chaque bloc l'adresse du bloc precedent (par exemple dans Mem[b-2]) */