Exo 2 ===== Q0. Le résultat est -1 car le code Ascii du caractère espace est plus petit que celui du caractère "C". La chaine "M2 CCI" est donc lexicographiquement plus petite que la chaine "M2CCI". Q1. Programme de test : #include #include #define N 256 int main() { char s1[N], s2[N] ; printf("chaine 1 ?\n") ; scanf("%s", s1) ; printf("chaine 2 ?\n") ; scanf("%s", s2) ; printf("resultat: %d\n", strcmp(s1, s2)) ; } Pour tester des chaines de longueur arbitraire plus grande que 255 il faudrait les représenter par des tableaux dynamiques ou des listes chaînées. Q2 Exemple de tests possibles 1. "ABC", "DEFG" (chaines sans caractères communs, resultat = -1) 2. "DEFG", "ABC" (chaines sans caractères communs, resultat = 1) 3. "ABC", "ABC" (chaines identiques non vides, resultat = 0) 4. "", "" (chaines identiques vides, resultat = 0) 5. "", "ABC" (comparaison à une chaine vide, resultat = -1) 6. "ABC", "" (comparaison à une chaine vide, resultat = 1) 7. "ABC", "AB" (chaines préfixes, resultat = 1) 8. "AB", "ABC" (chaines préfixes, resultat = -1) etc. Q3. La fonction proposée est erronnée car elle ne contrôle pas la longueur de S2. Par conséquent le résultat retourné peut être faux si une chaîne est préfixe de l'autre (avec un risque de débordement lors de l'accès à S2). Les tests 7 et 8 peuvent détecter cette erreur Q4. On peut corriger ce pb de la manière suivante : in mystrcmp(char *s1, char *s2) { unsigned int i=0 ; char result=0 ; while (s1[i] != '\0' && s2[i] != '\0') { if (s1[i] < s2[i]) { result = -1 ; break ; } ; if (s1[i] > s2[i]) { result = 1 ; break ; } ; i = i+1 ; } ; return result ; } EXO 3 ===== Q1. Contenu du fichier ResAlloc.h : #include #define N 255 #define Delta 360 typedef unsigned char Ressource ; typedef unsigned int Utilisateur ; typedef struct {Utilisateur u ; date d ; } Couple ; Couple Attribution[N] ; void initialiser() ; void acquerir (Utilisateur u, Ressource *r, int *ok); void liberer (Utilisateur u, Ressource r); Q2. Contenu du fichier ResAlloc.c #include "ResAlloc.h" void initialiser() { Ressource int i ; // toutes les ressources sont disponibles (date égale à 0) for(i=0; i 0 && Attribution[i].d > maxd) { // la ressource i est courramment la plus anciennement utilisée // depuis plus de delta secondes maxd = Attribution[i].d ; maxr=i ; } ; } ; if (maxd >= Delta) { // une ressource est préemptée Attribution[i].u = u ; // on l'attribue à u Attribution[i].d= date() ; // à l'instant courant ... *r = maxr ; *ok = 1 ; } else { // pas d'attribution possible ... *ok = 0 ; } ; } ; } void liberer (Utilisateur u, Ressource r) { // si la ressource r est attribuée à u alors elle est rendue disponible if (Attribution[r].u == u) Attribution[r].d = 0 ; } Q3. Programme principal int main() { int ok1, ok2; Ressource r1, r2; initaliser(); while (1) { acquerir (1, &r1, &ok1); attendre(200); acquerir (2, &r2, &ok2); attendre(300); if (ok1) { liberer(1, r1); attendre(100); if (ok2) { liberer(2, r2); } ; return 0; } Q4. Makefile test: ResAlloc.o date.o gcc -Wall -o test ResAlloc,.o date.o date.o: date.c date.h gcc -Wall -c date.c test.o: test.c ResAlloc.h date.h gcc -Wall -c test.c ResAlloc.o: ResAlloc.c ResAlloc.h date.h gcc -Wall -c ResAlloc.c Q5. Contenu du nouveau fichier ResAlloc.h #include #define N 255 #define P 10 #define Delta 360 typedef unsigned char Ressource ; typedef unsigned int Utilisateur ; typedef struct couple {Utilisateur u ; date d ; couple *suiv ; } Couple ; Couple *Attribution[N] ; // Attribution[i] est un pointeur sur un Couple void initialiser() ; void acquerir (Utilisateur u, Ressource *r, int *ok); void liberer (Utilisateur u, Ressource r); Q6. Contenu du nouveau fichier ResAlloc.c void initialiser() { Ressource int i ; // toutes les ressources sont disponibles for(i=0; iu == u) { /* suppression en tête */ Attribution[r] = c->suiv ; free(c) ; } else { pred = c ; c = c->suiv ; while (c != NULL && c->u != u) { pred = c ; c = c-> suiv ; } ; if (c != NULL) { /* suppression entre pred et c->suiv */ pred->suiv = c->suiv ; free(c) ; } ; } void acquerir (Utilisateur u, Ressource r, int *ok) { Couple *c, *max ; Date maxd ; unsigned int nbu=0 ; // nbre d'utilisateurs utilisant r // recherche d'une ressource disponible /* c est la liste des utilisateurs de r */ c = Attribution[r] ; maxd = Delta-1 ; while (c != NULL) { if (c->d > maxd) { // on met à jour le maximum maxd = c->d ; max = c ; } nbu = nbu +1 ; } ; if (nbu < P) { // insertion en tete de u dans Attribution[r] nouv = (Couple *)malloc(sizeof(Couple)) ; nouv->u = u ; nouv->d = date() ; nouv->suiv = Attribution[r] ; Attribution[r]= nouv ; *ok = 1 ; } else { if (maxd >= Delta) { // on preempte la resource utilisée par max->u ; max->u = u ; max->d = date() ; *ok = 1 ; } else { // pas d'attribution possible // la demande est rejetée ... *ok = ) ; } } } Q7. Un risque possible est un débordement arithmétique lors de l'incrémentation des "dates". Il y a environ 32 millions de secondes dans un an. Le plus grand entier non sigé sur 32 bits est de 4 milliards. Ce débordement se produirait donc environs 130 ans après 1970, soit en 2100 ...