Vous êtes sur la page 1sur 2

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

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


Examen du 14 mai 2012
Deux heures - Sans document.

Exercice 1 (Questions de cours)


1. A quoi correspondent les symboles ++ et -- en C++.
2. Ecrire précisément le prototype des méthodes qui permettent de définir le comportement de ces symboles pour
des objets d’une classe C donnée.

3. Donner un exemple d’une classe de la STL (Standard Template Library) pour laquelle les symboles ++ et --
sont définis. Ecrire un court exemple qui illustre l’utilisation de ++ avec un objet de cette classe.

Exercice 2 (Suites et accélération de convergence en C++)


On considère la classe abstraite suite définie par
class suite {
2 public :
suite ( double x0 , int n0 );
4 virtual void next () = 0;
protected :
6 int n , n0 ;
double xn , xn0 ;
8 };
qui permet de manipuler des suites réelles (xn )n≥n0 . Les champs n0 et xn0 sont destinés à stocker la condition
initiale. La méthode next() a pour but d’être surchargée dans les classes filles. C’est la fonction qui code le
passage de l’état (n, xn ) à l’état suivant (n + 1, xn+1 ).
1. Pourquoi dit-on que la classe suite est abstraite ?
Pourquoi les champs n, n0, xn, xn0 sont-ils protected ?

2. En utilisant la syntaxe de la liste d’initialisation propre au constructeur, définir le constructeur de la classe


suite qui doit initialiser les 4 champs protégés : n et n0 avec l’argument n0 et x et xn avec l’argument xn0. Les
arguments prendront la valeur 0 par défaut.

3. Surcharger l’opérateur [] qui renvoie une référence suite & initialisée par l’objet courant et qui a le comporte-
ment suivant :
– si l’argument k est plus grand que n on appelle la méthode next() jusqu’en k à partir de l’état courant,
– si l’argument k est plus petit que n on appelle la méthode next() jusqu’en k à partir de l’état initial.

4. Surcharger l’opérateur << qui permet l’affichage d’un objet d’une classe dérivée de suite. L’affichage sera
n x_n
Préciser le fichier d’en-tête (header) à inclure.
n
X (−1)k
On considère la suite des sommes partielles de la série de Leibniz sn = .
2k + 1
k=0

5. Ecrire une classe leibniz dérivée de suite qui code la suite (sn )n≥0 avec la condition initiale s0 = 1. La méthode
next() doit être redéfinie dans cette classe pour coder le passage de l’état (n, sn ) à l’état (n + 1, sn+1 ).

6. Ecrire un programme de test complet qui affiche les 10 premières itérations de la suite (sn )n≥0 .

On rappelle que la suite (sn )n≥0 converge vers π4 . La convergence est lente et une façon d’accélerer la convergence
est de mettre en œuvre le procédé Delta-2 de Aitken.
Le procédé Delta-2 est un procédé d’accélération de convergence (sous certaines conditions) qui associe à une
suite (xn )n≥0 , la suite (yn )n≥0 définie par

(xn+1 − xn )2
∀n ≥ 0, yn = xn − .
xn − 2xn+1 + xn+2

1
7. Définir une classe delta2 dérivée de suite qui permet d’implémenter le procédé Delta-2. Le constructeur devra
prendre pour argument une référence sur une suite.
Par exemple, pour manipuler la suite (yn )n≥0 obtenue comme procédé Delta-2 de la suite (sn )n≥0 on fera les
appels suivants
leibniz s (1 , 0);
2 delta2 y ( s );

8. Ecrire une fonction globale temps_convergence qui prend comme arguments une suite (xn )n≥0 et un paramètre
ε > 0, et qui renvoie le premier instant n > 0 tel que |xn − xn−1 | < ε (indiquer les modifications éventuelles à
faire sur la classe suite). Cette fonction utilise le polymorphisme dynamique et un appel sera
leibniz s (1 , 0);
2 int n = temps_convergence (s , 1e -6);

9. Ecrire un modèle de fonction (template) temps_convergence<T> qui permette un appel similaire à celui de la
question précédente.

Exercice 3 (Création d’une pile en C)


Une pile (ou stack) est une structure récursive (similaire en certains points à une liste chaînée) qui satisfait à
la règle LIFO (last in, first out) c’est à dire « dernier entré, premier sorti ». Les deux opérations élémentaires
que l’on peut faire sur une structure LIFO est d’empiler (push, i.e. ajouter un élément au sommet de la pile)
ou de dépiler (pop, i.e. retirer l’élément du sommet).
Voici, sur un exemple, comment on représente une structure LIFO :
sommet
– la pile est composée de 4 éléments dont les valeurs sont 1.5,
3.14159, 2 et 4.78,
1.5
– la pile a été créée en ajoutant successivement les valeurs 4.78
puis 2 puis 3.14159 et enfin 1.5,
– l’élément de valeur 1.5 est donc le dernier arrivé et il se trouve 3.14159
au sommet de la pile (premier élément de la structure récursive),
– l’adresse du premier élément est donnée par le pointeur sommet, 2
– on passe d’un élément à un autre en utilisant un pointeur (re-
présenté par une flèche),
– l’élément de valeur 4.78 pointe sur l’adresse NULL indiquant ainsi 4.78
qu’il s’agit du dernier de la pile.
NULL

1. Définissez une structure récursive struct element qui codera un élément de la pile (de double).
Redéfinir ce type en elt (pour faciliter l’écriture de la suite).

2. Définir le type pile comme une structure contenant 2 champs :


– nb_elt de type entier indiquant le nombre d’éléments dans la pile (0 si pile vide),
– sommet de type « pointeur sur elt » indiquant l’adresse du premier élément de la pile (NULL si pile vide).

3. Définir une fonction cree_pile qui crée une pile vide (i.e. nb_elt = 0 et sommet = NULL) et qui renvoie l’adresse
de cette pile vide (un pointeur sur le type pile) si la création est réussie et qui renvoie NULL sinon.

4. Ecrire une fonction empile (ou push) qui ajoute un élément au sommet de la pile. Cette fonction doit prendre 2
arguments et renvoyer un entier : 1 si l’ajout est réussi et 0 sinon.
Ecrire une fonction depile (ou pop) qui renvoie la valeur du premier élément de la pile avant de le détruire.

5. En utilisant une boucle for, écrire une fonction vide qui détruit une pile (destruction de tous les éléments).

6. Ecrire un court programme qui crée la pile donnée en exemple.

Vous aimerez peut-être aussi