Examen LI205 12 décembre 2007 Université Pierre et Marie Curie Votre numéro d anonymat : Initiation à la programmation impérative en C LI205 Examen du 12 décembre 2007 (2 heures) Seulement les fiches de cours sont autorisées Les calculatrices, baladeurs et autres appareils électroniques sont interdits. Les téléphones mobiles doivent être éteints et rangés dans les sacs. Le barème sur 70 points n a qu une valeur indicative. Avant de commencer, vérifiez que votre copie contient 12 pages avec 22 questions. Attention : Dans les programmes à compléter, les parties à remplir sont généralement mises en évidence par des traits, mais il est possible que dans certains cas vous soyez amenés à ajouter des lignes vous-mêmes. 1 Question de cours (6 pts) Question 1 (2 points) Dans quel cas vaut-il mieux utiliser une boucle do-while plutôt qu une autre boucle? Expliquez. Question 2 (2 points) Donnez la signature de la fonction majuscule qui retourne le nombre de majuscules dans un tableau de caractères de taille quelconque. Question 3 (2 points) Déclarer le type d enregistrement personne défini par un nom, un prénom et un âge.
2 Debug (4 pts) Question 4 (4 points) On considère le programme suivant : int main() { int i, int j; for(i=0;i<10;i++) { j = j+2*i; printf("j=%d\n",j); On obtient les erreurs suivantes à la compilation : Prompt> gcc -Wall -Werror -O -o debug debug.c debug.c: In function "main": debug.c:2: erreur: expected identifier or "(" before "int" debug.c:4: erreur: "j" undeclared (first use in this function) debug.c:4: erreur: (Each undeclared identifier is reported only once debug.c:4: erreur: for each function it appears in.) cc1: warnings being treated as errors debug.c:4: attention : "j" is used uninitialized in this function debug.c:6: attention : implicit declaration of function "printf" debug.c:6: attention : incompatible implicit declaration of built-in function " debug.c:7: attention : control reaches end of non-void function Déduisez-en les quatre erreurs dans ce programme et proposez des corrections. 1. 2. 3. 4. Examen LI205 12 décembre 2007 UPMC Licence d informatique page 2 sur 12
3 Opérations de base (10 pts) Question 5 (3 points) On souhaite écrire un programme C qui demande à l utilisateur de saisir une valeur flottante et, lorsque cette valeur est positive, affiche à l écran la partie entière de la moitié de la valeur saisie. Complétez le programme : #include <stdio.h> int main() { printf("entrez une valeur : "); scanf( ); if (v>0) { printf(" ", ); return 0; Question 6 (3 points) Modifiez le programme précédent de manière à ce que : 1. Le programme demande de saisir une valeur plus grande qu une valeur LIMITE de votre choix. 2. Le résultat ne soit affiché que lorsque la valeur saisie est supérieure à LIMITE. 3. Lorsque la valeur saisie est plus petite ou égale à la limite, le programme choisisse une valeur entière aléatoirement entre -LIMITE et LIMITE et affiche cette valeur. La valeur tirée doit être différente à chaque nouvelle exécution du programme. Rappel : la fonction rand de la bibliothèque stdlib permet d obtenir un nombre entier pseudoaléatoire entre 0 et MAX_RAND. On peut redéfinir la graine de la suite pseudo-aléatoire en utilisant la fonction srand. Examen LI205 12 décembre 2007 UPMC Licence d informatique page 3 sur 12
Question 7 (4 points) La règle établie par le conseil d administration de l Université de Saint Glinglin pour déterminer si un étudiant est reçu à l examen est très complexe : Les étudiants passent 3 examens (numérotés 1, 2 et 3). Si un étudiant a plus de 8/20 à l examen 1, alors il est admis. Si un étudiant a 8/20 ou moins à l examen 1, alors il faut qu il ait au moins la moyenne à chacun des examens 2 et 3. Un cas particulier a été voté pour le cas précédent : un étudiant qui a eu 20 à l examen 3 est systématiquement reçu. Écrivez une fonction C admis qui prend en paramètre les trois notes n1, n2 et n3 d un étudiant et qui renvoie 1 ou 0 selon que l étudiant est reçu ou non. int admis(int n1, int n2, int n3) { Examen LI205 12 décembre 2007 UPMC Licence d informatique page 4 sur 12
4 Boucles (7 pts) Question 8 (2 points) Nous voulons identifier les palindromes (les mots qui se lisent de façon identique de la droite vers la gauche et de la gauche vers la droite). Nous allons tout d abord réaliser l algorithme suivant où tab est un tableau de n caractères. : Initialiser un entier i a 0 et un entier j a n-1 Parcourir le tableau tab Si ( i > j ou tab[i]!=tab[j] ) On arrete le parcours Sinon On augmente i de 1, on diminue j de 1 et On continue le parcours Quel est le type de boucle le mieux adapté pour réaliser cet algorithme? Justifiez votre réponse. Question 9 (3 points) Complétez le code suivant qui doit réaliser l algorithme précédent. Les lignes à compléter sont données à titre indicatif, à vous de voir si elles doivent toutes être remplies. int i=0, j=n-1; { i++; j--; Examen LI205 12 décembre 2007 UPMC Licence d informatique page 5 sur 12
Question 10 (2 points) À la sortie de la boucle précédente, quelle condition vous permet de dire que les caractères contenus dans tab forment un palindrome? 5 Fonctions et programmes (13 pts) Question 11 (4 points) Ecrivez les fonctions sommetab1 et sommetab2 qui sont compatibles avec la fonction main suivante. Les commentaires vous indiquent ce que doit faire chacune des fonctions. int main() { int tab[]={1,5,4,8,9,6,1,4,5,-2,-4; /* sommetab1 affiche la somme des N premiers elements de tab */ sommetab1(tab,5); /* sommetab2 renvoie la somme des N premiers elements de tab */ printf("la somme des 10 premiers elements du tableau est %d\n", sommetab2(tab,10)); return 0; sommetab1( ) { Examen LI205 12 décembre 2007 UPMC Licence d informatique page 6 sur 12
sommetab2( ) { Question 12 (2 points) Quels doivent être les paramètres effectifs de la fonction sommetab1 pour obtenir l affichage de la somme des quatre premiers éléments du tableau tab? Question 13 (4 points) Qu affiche le programme suivant? #include <stdio.h> int a=10; int b=5; int *c=&a; int f(int x, int *c) { int a; a = *c; *c = b; b = x; x = a; return(a+*c); int g(int b) { *c=2*b; b=a+b; return(b); Examen LI205 12 décembre 2007 UPMC Licence d informatique page 7 sur 12
int main() { int x=3, y=7, z, b=3; printf("a=%d b=%d x=%d y=%d z=%d \n", a, b, x, y, z); z=f(a,&x); printf("a=%d b=%d x=%d y=%d z=%d \n", a, b, x, y, z); a=g(y); printf("a=%d b=%d x=%d y=%d z=%d \n", a, b, x, y, z); return(0); a = b = x = y = z = a = b = x = y = z = a = b = x = y = z = Question 14 (3 points) Pouvez-vous modifier le programme pour qu il n y ait plus de variable globale? Justifiez votre réponse pour chacune des variables. Examen LI205 12 décembre 2007 UPMC Licence d informatique page 8 sur 12
6 Récursivité (6 pts) Question 15 (2 points) Soit la fonction : float fonction(float x, int n) { if (n == 0) { return 1.0; else { return x * x * fonction(x, n-2); Qu affiche l instruction suivante? printf("fonction de %f, %d : %f\n", 2.0, 5, fonction(2.0,5)); Question 16 (4 points) La représentation d un nombre N en base K est obtenue à partir des restes des divisions successives de N par K. Par exemple, la représentation de 21 en base 3 est obtenue par les calculs successifs : 21 = 7 * 3 + 0 7 = 2 * 3 + 1 2 = 0 * 3 + 2, soit un résultat final égal à 210. Écrivez une fonction récursive qui prend en paramètre un nombre n et qui affiche sa représentation en base 2. Examen LI205 12 décembre 2007 UPMC Licence d informatique page 9 sur 12
7 Tableaux (24 pts) Nous souhaitons dans cette partie utiliser un tableau pour gérer les places disponibles d une salle de spectacles. Chaque indice du tableau correspond à un numéro de place. Les places occupées sont représentées par une valeur 1 dans la case correspondante, les places disponibles par la valeur 0. La capacité totale de la salle est de TAILLE sièges. Question 17 (4 points) Écrivez une fonction compte_dispo qui renvoie le nombre de sièges encore disponibles dans la salle. Question 18 (3 points) Écrivez un programme qui permet de tester votre fonction sur le tableau suivant : 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 Question 19 (6 points) Les réservations peuvent concerner un groupe de nb personnes qui souhaitent être placées côte à côte. Il faut alors rechercher nb sièges consécutifs disponibles. Nous nous proposons, pour effectuer ces réservations groupées, d utiliser l algorithme suivant : Examen LI205 12 décembre 2007 UPMC Licence d informatique page 10 sur 12
L algorithme utilise une variable i pour parcourir le tableau, une variable deb pour reperer le debut d un bloc vide et une variable cpt pour mesurer la taille de ce bloc Tant que tout le tableau n a pas ete parcouru faire Se deplacer jusqu au debut d un bloc vide ; Si la fin du tableau n est pas atteinte, Initialiser le repere deb et la taille du bloc Parcourir entierement le bloc vide en calculant sa taille Si la taille est suffisante, Renvoyer l indice du premier element du bloc Renvoyer -1 si aucun bloc n a ete trouve Utilisez cet algorithme pour écrire une fonction test_ok qui renvoie la position du premier siège d un bloc libre pouvant satisfaire une demande de nb sièges voisins, -1 si aucun bloc de ce type n existe. Examen LI205 12 décembre 2007 UPMC Licence d informatique page 11 sur 12
Question 20 (4 points) Écrivez une fonction reserver qui utilise la fonction test_ok pour effectuer la réservation, c est-àdire faire passer les sièges concernés de l état libre à l état occupé. Cette fonction renvoie la position à laquelle la réservation a été effectuée, -1 si aucun bloc ne permettait de la satisfaire. Question 21 (3 points) Que faut-il modifier dans la fonction test_ok pour que la fonction reserver puisse récupérer, en plus de la position à laquelle effectuer la réservation, la taille du bloc de sièges libres dans lequel la réservation est faite? Question 22 (4 points) Écrivez une fonction best_fit qui recherche le plus petit bloc libre contenant au moins nb sièges. Examen LI205 12 décembre 2007 UPMC Licence d informatique page 12 sur 12