Révision pour le final
Transcription
Révision pour le final
Nom Prénom Code permanent Examen final Date : 25 avril 2016 Titre du cours : Construction et maintenance de logiciels Sigle et groupe : INF3135 Enseignant : Alexandre Blondin Massé Instructions 1) Vous avez trois heures pour répondre à l’examen ; 2) Vous avez droit à toute votre documentation ; 3) Il est interdit d’utiliser un ordinateur, peu importe sa taille et sa forme (téléphone portable, agenda électronique, etc.) ; 4) Il est interdit de parler et de prêter de la documentation à un autre étudiant ; 5) À moins d’avis contraire, justifiez toutes vos réponses et donnez le détail de vos calculs ; 6) Indiquez clairement vos réponses finales ; Question 1 2 3 4 5 6 Total Sur 20 15 20 20 15 10 100 Note INF3135 — Construction et maintenance de logiciels Hiver 2016 Question 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (20 points) Considérez l’interface queue.h suivante : #include <stdbool.h> // Types // ----struct QueueNode { char *content; // Contenu du noeud struct QueueNode *prev; // Noeud precedent struct QueueNode *next; // Noeud suivant }; struct Queue { struct QueueNode *first; // Pointeur vers le premier noeud struct QueueNode *last; // Pointeur vers le dernier noeud }; // Prototypes // ---------/** * Cree une file vide. * * @return Une file vide */ struct Queue *queueCreate(); /** * Retourne vrai si la file est vide. * * @param queue Un pointeur vers la file Vrai si et seulement si la file est vide * @return */ bool queueIsEmpty(const struct Queue *queue); /** * Insere un element en queue de file. * * Note : La chaine de caracteres du contenu doit etre dupliquee * via la fonction strdup. * Un pointeur vers la file * @param queue * @param content Le contenu de l’element a inserer */ void queuePush(struct Queue *queue, char *content); /** * Retourne l’element en tete de file. * * @param queue Un pointeur vers la file La valeur contenue dans le noeud * @return */ char *queueFirst(struct Queue *queue); /** * Supprime l’element en tete de file. * * @param queue Un pointeur vers la file */ void queuePop(struct Queue *queue); /** * Detruit cette file. * Page 2 de 16 INF3135 — Construction et maintenance de logiciels Hiver 2016 * @param queue Un pointeur vers la file */ void queueDelete(struct Queue *queue); Proposez une implémentation de cette interface qui respecte la documentation et qui ne produit aucune erreur de compilation, de segmentation ni de fuite mémoire. Page 3 de 16 INF3135 — Construction et maintenance de logiciels Page 4 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels Hiver 2016 Question 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (15 points) Ces questions à réponses courtes portent sur SDL. (a) (3 points) La bibliothèque SDL ne supporte par défaut qu’un seul type de format d’image et un seul type de format audio. Quels sont-ils ? (a) (b) (3 points) Nommez la bibliothèque principale qui fournit un support pour le format PNG dans SDL. (b) (c) (3 points) Vrai ou faux ? Une variable de type Mix Chunk permet de représenter un échantillon sonore qui peut être joué au plus une fois. (c) (d) (3 points) Dans une application graphique SDL, la fonction SDL RenderPresent devrait idéalement être appelée exactement une fois par tour de boucle principale. (d) (e) (3 points) Expliquez en quelques mots l’intérêt d’utiliser une feuille de sprites dans une application graphique. Page 5 de 16 INF3135 — Construction et maintenance de logiciels Hiver 2016 Question 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (20 points) En annexe (page 14) se trouve le fichier array.c vu en classe un peu plus tôt dans la session. Pour simplifier, les fonctions ne sont pas divisés entre un fichier .h et un fichier .c, même s’il s’agit d’une meilleure pratique. Proposez des préconditions et postconditions, ainsi que les assertions correspondantes, pour chacune des 4 méthodes suivantes (s’il y a lieu) : • arrayInsert ; • arrayRemove ; • arrayHasElement ; • arrayGet. Soyez le plus exhaustif possible. Page 6 de 16 INF3135 — Construction et maintenance de logiciels Page 7 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels Hiver 2016 Question 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (20 points) Considérez le fichier XML suivant (nommé exemple.xml) : <?xml version=’1.0’ encoding=’us-ascii’?> <!-- A SAMPLE set of slides --> <slideshow title="Sample Slide Show" date="Date of publication" author="Yours Truly" > <!-- TITLE SLIDE --> <slide type="all"> <title>Wake up to WonderWidgets!</title> </slide> <!-- OVERVIEW --> <slide type="all"> <title>Overview</title> <item>Why <em>WonderWidgets</em> are great</item> <item/> <item>Who <em>buys</em> WonderWidgets</item> </slide> </slideshow> Écrivez un script Python utilisant le module re qui permet de récupérer tous les titres présents dans un fichier ayant une syntaxe similaire à celle du fichier ci-haut. Par exemple, dans l’exemple ci-haut, votre script devrait afficher quelque chose du genre : Sample Slide Show Wake up to WonderWidgets! Overview Note : Le script devrait être relativement court. Vous serez pénalisés si vous proposez une solution inutilement compliquée. Page 8 de 16 INF3135 — Construction et maintenance de logiciels Page 9 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels Hiver 2016 Question 5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (15 points) Sous UNIX, la commande rm permet de supprimer un ou plusieurs fichiers. Elle accepte différentes options. En particulier, la commande rm -rf <rep> supprime récursivement le répertoire <rep>, tous les fichiers qu’il contient, ainsi que tous les sous-répertoires contenus dans <rep>. En n’utilisant que les commandes cd, rm (sans utiliser une option telle que -r ou -f), rmdir (qui supprime un répertoire vide) ainsi que les structures conditionnelles en Bash, proposez un script (Bash) nommé rmrf qui a le même effet que la commande rm -rf. Note : Il vous faut deux informations additionnelles que nous n’avons pas vues en classe pour répondre à cette question : • Dans un script Bash, il est possible de récupérer l’argument passé lors de l’appel à l’aide de la syntaxe $1. Autrement dit, si on lance la commande rmrf projets, alors la chaı̂ne de caractères projets peut être récupérée dans le script Bash dans la variable spéciale $1. Notez que vous n’avez pas à valider si le répertoire $1 existe réellement : on suppose qu’il existe toujours. • On peut tester si une variable, disons $nom, correspond à un fichier à l’aide de l’expression if [ -f "$nom" ] ou s’il s’agit plutôt d’un répertoire avec if [ -d "$nom" ] Remarque : La solution ne prend pas plus de 10 lignes. Page 10 de 16 INF3135 — Construction et maintenance de logiciels Page 11 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels Hiver 2016 Question 6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . (10 points) Optimisez le plus possible le code suivant : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> #include <stdbool.h> #include <math.h> struct Point { float x; float y; }; float distance(struct Point p1, struct Point p2) { return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2)); } bool sontProches(struct Point p1, struct Point p2) { return distance(p1, p2) <= 2; } int main() { struct Point p1 = {2, 3}; struct Point p2 = {-1, 4}; printf("Les points sont %s\n", sontProches(p1, p2) ? "proches" : "eloignes"); } Attention : assurez-vous que le code final se comporte exactement de la même façon que le code initial. Note : N’hésitez pas à ajouter des fonction supplémentaires ou en modifier si nécessaire. Page 12 de 16 INF3135 — Construction et maintenance de logiciels Page 13 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels Annexe A : array.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> // Types // ----typedef struct { int *values; // Les valeurs dans le tableau int currentSize; // Le nombre d’elements dans le tableau int capacity; // Capacite du tableau } Array; // Prototypes // ---------Array arrayCreate(); void arrayInsert(Array *a, int element); void arrayRemove(Array *a, int i); bool arrayHasElement(const Array *a, int element); int arrayGet(const Array *a, int i); void arrayDelete(Array *a); // Operations // ---------/** * Cree un tableau dynamique vide et le retourne. * * @returns Le tableau */ Array arrayCreate() { Array a; a.values = (int*)malloc(sizeof(int)); a.currentSize = 0; a.capacity = 1; return a; } /** * Insere un element en fin de tableau. * * Le tableau est redimensionne si sa capacite maximale * est atteinte. * Le tableau * @param a * @param element L’element a inserer dans le tableau */ void arrayInsert(Array *a, int element) { if (a->currentSize >= a->capacity) { a->capacity *= 2; realloc(a->values, a->capacity * sizeof(int)); } a->values[a->currentSize] = element; ++a->currentSize; } /** * Supprime l’element en position i et decale les * valeurs suivantes d’un indice vers la gauche. * * @param a Le tableau * @param i La position de l’element a supprimer */ Page 14 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 void arrayRemove(Array *a, int i) { if (0 <= i && i < a->currentSize) { ++i; while (i < a->currentSize) { a->values[i - 1] = a->values[i]; ++i; } --a->currentSize; } else { printf("Remove: invalid index %d (size = %d)\n", i, a->currentSize); } } /** * Retourne vrai si et seulement si le tableau contient * l’element donne. * Le tableau * @param a * @param element L’element a verifier Vrai si et seulement si l’element est present * @returns */ bool arrayHasElement(const Array *a, int element) { int i = 0; while (i < a->currentSize && arrayGet(a, i) != element) { ++i; } return i < a->currentSize; } /** * Retourne l’element en position i dans le tableau. * * @param a Le tableau * @param i La position de l’element voulu * @returns L’element en position i */ int arrayGet(const Array *a, int i) { if (0 <= i && i < a->currentSize) { return a->values[i]; } else { printf("Get: invalid index %d (size = %d)\n", i, a->currentSize); return -1; } } /** * Affiche un tableau sur la sortie standard. * * @param a Le tableau a afficher */ void arrayPrint(const Array *a) { int i; printf("["); for (i = 0; i < a->currentSize; ++i) { printf(" %d", a->values[i]); } printf(" ]"); } /** * Supprime un tableau dynamique. * * @param a Le tableau */ Page 15 de 16 Hiver 2016 INF3135 — Construction et maintenance de logiciels 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 void arrayDelete(Array *a) { free(a->values); } // Main // ---int main() { Array a = arrayCreate(); printf("Inserting 3, 2, 5, 7, 8, 7\n"); arrayInsert(&a, 3); arrayInsert(&a, 2); arrayInsert(&a, 5); arrayInsert(&a, 7); arrayInsert(&a, 8); arrayInsert(&a, 7); arrayPrint(&a); printf("\nRemoving at position 2\n"); arrayRemove(&a, 2); arrayPrint(&a); printf("\nRemoving at position 4\n"); arrayRemove(&a, 4); arrayPrint(&a); printf("\nRemoving at position 4\n"); arrayRemove(&a, 4); arrayPrint(&a); printf("\nHas element %d ? %s\n", 5, arrayHasElement(&a, 5) ? "yes" : "no"); printf("Has element %d ? %s\n", 2, arrayHasElement(&a, 2) ? "yes" : "no"); arrayDelete(&a); } Page 16 de 16 Hiver 2016