M2 CCI - Corrigé du DS d'octobre 2022 ===================================== Exercice 1 [4 pts] ========== Q1. [2 pts] Pour X=0, X=10 et X=240 on obtient uniquement "ok1" sur l'écran Q2. [2 pts] Pour X=250 on obtient : ko1 ko2 On pourrait s'attendre à ce que x+10 provoque un débordement arithmétique et donc que x+10=4 (car 250+10 modulo 255 = 4). En fait la variable x est (implicitement) convertie en int lors de l'évaluation de x+10 < 255. C'est pourquoi les deux branches notées "ko1" et "ko2" sont exécutées. Si le programme initial avait été : #include #define X 250 int main(){ unsigned char x = X; unsigned char y; y=x+10 ; // ON CALCULE x+10 DANS UNE VARIABLE DE TYPE UNSIGNED CHAR if (x < 255) { if (y < 255) printf("ok1\n") ; else printf("ko1\n") ; } ; if (y > 255) { if (x > 255) printf("ok2\n") ; else printf("ko2\n") ; } ; } Alors l'affichage obtenu aurait été "ok1" ... Exercice 2 [8 pts] ========== Q1. [3 pts] #include #define L 7 int main() { unsigned int T[L+1] ; // ATTENTION, tableau de taille L+1 ! unsigned char i, ideb, cour ; // lecture de la sequence initiale for (i=0 ; i<=L ; i++) { printf("valeur ? ") ; scanf ("%d", &(T[i])) ; } ; // recherche du premier element non nul i = 0 ; while (i<=L && T[i] == 0) i = i+1 ; ideb = i ; // indice du premier element de la sequence resultat // mise a jour des elements suivants while (i<=L) { // cour est l'element non nul courant cour = T[i] ; // on remplace tous les element nuls suivants par cour i = i+1 ; while (i <= L && T[i] == 0) { T[i] = cour ; i = i + 1 ; } ; } ; // affichage du resulat for (i=ideb ; i<=L ; i++) { printf ("%d\n", T[i]) ; } ; return 0 ; } Q2. [2 pts] Il faut essayer de tester ce programme de manière à "couvrir" les différentes valeurs possibles en entrée ... Par exemple : - une séquence ne contenant que des 0 - une séquence contenant aucun 0 - une séquence dans laquelle valeurs nullles et non-nulles alternent : 0 1 0 1 0 1 0 1 (commence par une valeur nulle) ou 1 0 1 0 1 0 1 0 (commence par une valeur non nulle) - une séquence avec plusieurs 0 consécutifs : 0 0 0 0 1 2 3 4 (en début) 1 2 3 4 0 0 0 0 (en fin) 0 0 1 2 0 1 3 0 (un peu partout !) Il est bien sur difficile de garantir sur un programme de ce type que l'on a couvert l'ensemble des executions possibles ... Q3. [2 pts] Pour déclarer la séquence R : unsigned int R[L+2] ; // IL FAUT PREVOIR UNE CASE DE PLUS POUR LA MARQUE DE FIN ! Pour construire la séquence R on peut simplement remplacer l'affichage de la séquence résultat par : // construction de la sequence resultat R j = 0 ; for (i=ideb ; i<=L ; i++) { /* parcours de la sequence resultat stockee dans T et copie dans R */ R[j] = T[i] ; j = j+1 ; } ; R[j] = 0 ; // ON TERMINE PAR LA MARQUE DE FIN ... Q4. [1 pt] On peut utiliser 0 comme marque de fin de la séquence résultat R car l'on sait que la valeur 0 n'est pas une valeur possible dans cette séquence. Cela n'est pas le cas dans la séquence initiale T ... Exercice 3 [8 pts] ========== Q1. [ 2pts] #define L 10 // longueur d'un identifiant typedef struct { unsigned int largeur ; unsigned int longueur ; } Taille ; typedef enum {Rouge, Noir, Bleu, Vert} Couleur ; typedef struct { unsigned int prix ; Couleur couleur ; Taille taille ; char identifiant[L+1] ; // on ajoute une case pour la marque de fin int enStock ; // booleen } ; Q2. [2 pts] Article a1, a2 ; if ( a1.prix == a2.prix && a1.couleur == a2.couleur && a1.taille.largeur == a2.taille.largeur && a1.taille.longueur == a2.taille.longueur && !strcmp(a1.identifiant, a2.identifiant) && a1.enStock == a2.enStock ) { /* a1 et a2 sont egaux */ } else { /* a1 et a2 sont differents */ } Q3. [2 pts] Article a1 ; unsigned int xa1 ; // entier associé à a1 xa1 = a1.prix ; xa1 = xa1 + a1.couleur ; xa1 = xa1 + a1.taille.largeur + a1.taille.longueur ; for (i=0; i