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