Vous êtes sur la page 1sur 3

Université Pierre et Marie Curie Master M1 "Mathématiques et Applications"

Période 2 - 2012/2013 Programmation en C/C++


Examen du 17 mai 2013
Deux heures - Sans document.

Exercice 1 (Questions de cours)


1. Donner la définition vue en cours du type statique d’une variable, et celle du type dynamique.
On considère la définition des classes X et Y donnée dans le code suivant
struct X {
2 void print () const { std :: cout << " Je suis X " << std :: endl ; };
};
4 struct Y : public X {
void print () const { std :: cout << " Je suis Y " << std :: endl ; };
6 };
et la déclaration des variables ObjX, ObjY, A, B, C, et D
X ObjX ;
2 Y ObjY ;
X & A = ObjX ;
4 X & B = ObjY ;
X C = ObjY ;
6 Y & D = ObjY ;

2. Quels sont les types (statique et dynamique) des variables A, B, C, et D ?

3. Les appels suivants sont-ils corrects ? Si oui, que donnent-ils ?


A - > print ();
2 B . print ();
C . print ();
4 (* D ). print ();

On considère maintenant le pointeur E initialisé de la façon suivante X * E = & ObjY.


4. Donner le type statique et le type dynamique de E.

5. Comment modifier les classes X et Y pour que l’appel de E->print() affiche “Je suis Y” ? Justifier précisément
votre modification.
Quels changements apportent cette modification sur les appels de la question 3. ?

Exercice 2 (Recherche dichotomique en C)


La fonction bsearch existe dans la librairie standard du C et permet une recherche par dichotomie d’un élément
dans un tableau trié. Voici les informations tirées de la documentation de la librairie standard :
# include < stdlib .h >
2 void * bsearch ( const void * cle , const void * base ,
unsigned nmemb , unsigned size ,
4 int (* compar )( const void * , const void *));

La fonction bsearch recherche l’objet correspondant à la cle, dans une table de nmemb objets, com-
mençant à l’adresse base. La taille des éléments de la table est indiquée dans size.
Le contenu de la table doit être triée en ordre croissant par rapport à la fonction de comparaison
référencée par compar. La routine compar doit être capable de recevoir deux arguments, le premier
pointant sur l’objet cle, et le second sur un élément de la table (l’ordre des arguments est toujours
respecté par bsearch). Cette routine doit retourner une valeur entière respectivement inférieure, égale,
ou supérieure à zéro si l’objet cle est inférieur, égal, ou supérieur à l’élément de la table.
La fonction bsearch renvoie un pointeur sur l’élément correspondant à celui recherché, ou NULL si
aucun élément ne correspond. Si plusieurs élements de la table correspondent à la cle, celui qui est
renvoyé n’est pas spécifié.
1. Que signifie const void * et quel est le type de l’argument compar de la fonction bsearch ?

1
2. Ecrire un programme court qui crée un tableau contenant les valeurs {1, 2.718, 3.142, 10}, puis qui appelle
la fonction bsearch pour chercher une valeur x dans ce tableau. Afficher un message si la valeur x n’est pas dans
le tableau.

3. Créer une structure Complex qui contient 2 champs : la partie réelle et la partie imaginaire d’un nombre complexe.

4. Ecrire la fonction compare_module qui compare le module de 2 nombres complexes. Le prototype de cette fonction
doit être compatible avec celui de l’argument compar de la fonction bsearch.

5. Ecrire un programme court qui cherche un nombre complexe donné dans le tableau suivant : i, 1 + 2i , 1 + 2i, 4 .


Exercice 3 (Interpolation en C++)


Le but est d’implémenter une classe permettant de construire le polynôme d’interpolation de Lagrange de
n points (x1 , y1 ), . . . , (xn , yn ) et de l’évaluer facilement en tout point réel. Dans toute la suite on suppose
x1 < x2 < · · · < xn . Le polynôme de Lagrange est le polynôme P de degré n − 1 defini par
n
X Y (x − xj )
P (x) = yi (1)
i=1
(xi − xj )
j6=i

vérifiant en particulier P (xi ) = yi .


Dans un premier temps, on code une classe abstraite Interpol. Cette classe a pour but d’avoir des classes filles
qui réutilisent les champs et les méthodes de cette classe abstraite. Voici la définition partielle de la classe
Interpol.
class Interpol {
2 public :
Interpol ( std :: string nom_fichier , int n );
4 virtual double operator ()( double x ) = 0;
protected :
6 int n ;
double * points_x , * points_y , * poids ;
8 };

On définit le constructeur de la façon suivante :


Interpol :: Interpol ( std :: string nom_fichier , int n ) : n ( n ) {
2 std :: ifstream file ( nom_fichier . c_str ());
points_x = new double [ n ];
4 points_y = new double [ n ];
poids = new double [ n ];
6 for ( int i = 0; i < n ; ++ i ) {
file >> points_x [ i ] >> points_y [ i ];
8 }
file . close ();
10 };

Le constructeur défini ci-dessus alloue les différentes zones mémoires utilisées par la classe (plus précisément un
objet d’une classe fille non abstraite). Pour simplifier, on allouera n double pour chacun des champs points_x,
points_y, poids. L’initialisation des champs points_x et points_y se fait à partir des n premières lignes d’un fichier
texte qui contient 2 colonnes : la première codant les (xk )k=1,...,n et la seconde les (yk )k=1,...,n . L’initialisation
du champ poids se fera dans les constructeurs des classes filles.

1. Pourquoi la classe Interpol est-elle appelée classe abstraite ?

2. Etant donné que les champs points_x, points_y et poids sont des adresses vers des zones mémoires en dehors
de la classe, quelles sont les 3 méthodes à redéfinir obligatoirement ?
Ecrire le code de ces 3 méthodes.

3. Ajouter une méthode min() à cette classe qui renvoie le plus petit point xk pour k ∈ {1, . . . , n}.
Définir de la même façon une méthode max().

2
Interpolation linéaire
Pour tester cette classe abstraite, on définit une classe InterpolLin dérivée (publiquement) de Interpol qui
permet d’implémenter l’interpolation linéaire entre les points ((xk , yk )k=1,...,n ). Il s’agit de la fonction l définie
par
∀x ∈ [xk , xk+1 ], l(x) = yk + ak (x − xk ),
l(x) = y1 si x ≤ x1 et l(x) = yn si x ≥ xn . Les réels ak sont les poids de l’interpolation.
Un code pour tester cette classe serait par exemple :
InterpolLin h ( " points . dat " , 7);
2 for ( double x = h . min () -1; x <= h . max ()+1; x += 0.2)
cout << x << " \ t " << h ( x ) << endl ;

4. Définir la classe InterpolLin comme classe fille de Interpol ainsi que le constructeur appelé dans cet exemple :
le constructeur devra appeler celui de la classe mère et définir les points (ak )k=1,...,n utilisés pour l’interpolation
linéaire dans le champ poids.

5. Définir l’opérateur fonctionnel operator() (qui redéfinit alors celui de la classe mère Interpol).

Interpolation polynômiale
Le polynôme de Lagrange P défini en (1) peut se réécrire (sous forme de Newton) de la façon suivante
n
X
∀x, P (x) = y1 + a1,...,k (x − x1 ) . . . (x − xk−1 ), (2)
k=2

où pour tout i ∈ {1, . . . , n}, et j tel que i + j ∈ {1, . . . , n}, le coefficient ai,...,j est défini récursivement par
−ai,...,i+j−1
( a
ai,...,i+j = i+1,...,i+j
xi+j −xi ,
ak,k = yk , ∀k ∈ {1, . . . , n}.

De façon similaire à la classe InterpolLin, on définit une classe InterpolPoly dérivée de Interpol.
6. Définir la classe InterpolPoly et son constructeur qui appelle celui de la classe mère et initilialise le champ poids
avec les a1,..,k pour k = 2, . . . , n.

7. Définir l’opérateur () et écrire un programme de test complet.

Avec la STL
8. Quel conteneur de la librairie standard (STL) peut être utilisé pour stocker les valeurs des champs points_x,
points_y et poids ?
Modifier le code du constructeur de la classe Interpol en conséquence.

Vous aimerez peut-être aussi