UNIVERSITE DE LA MANOUBA
-----¤¤¤¤-----
ECOLE NATIONALE DES SCIENCES
DE L'INFORMATIQUE
ANNEE UNIVERSITAIRE
2010-2011
Matière : Programmation Orientée Objets
Niveau : II1
Enseignants : Y. JAMOUSSI, K. BEN RHOUMA, R.CHEBIL, S. MTIBAA, O. FAKHFAKH
Date : vendredi 8 avril 2011
Durée: 2H
Documents : Non autorisés
Devoir surveillé
- Nombre de pages = Sujet (2 pages) + 2 formulaires A3 à rendre (de 1/8 à 8/8)
- Les réponses hors sujet seront notées négativement
Exercice n°1 (6 pts) : (les questions se trouvent dans les pages de 1/8 à 2/8)
Soit les deux classes A et B suivantes :
class A {
private:
int * ptr;
public:
A() : ptr(NULL)
{
cout << "A::A()" << endl;
}
A( int a ) : ptr(new int(a))
{
cout << "A::A(" << a << ")" << endl;
}
class B {
private:
A att;
public:
B() : att(1)
{
cout << "B::B()" << endl;
}
B(int n)
{
att = A(n);
cout << "B::B(" << n << ")" << endl;
Publicité
}
~A() { delete ptr; }
~B() { cout << "B::~B()" << endl; }
void operator = (const A & arg)
{
cout << "operateur =" << endl;
if (&arg != this)
{
ptr = new int( *(arg.ptr) );
}
}
void afficher() const
{
cout << "A::ptr=" << ptr << endl;
}
};
void B::afficher() const
{
cout << "B::";
att.afficher();
}
void f(A arg)
{
att = arg;
afficher();
}
};
Exercice n°2 (5,5 pts) : (les questions se trouvent dans les pages de 2/8 à 4/8)
En mathématiques, un nombre rationnel est celui qui peut être représenté comme une fraction dont le numérateur
et le dénominateur sont deux entiers. 0,5 = ½ et 1,3125 = 21/16 sont deux nombres rationnels. Cependant, la
racine carrée de 2 n’est pas un nombre rationnel; vous ne pouvez pas l'exprimer comme le rapport de deux
entiers.
Certains calculs pourraient bénéficier du type de données fraction, qui préserve le numérateur et le dénominateur
séparément. Par exemple, un problème inhérent à tous les ordinateurs est l’inexactitude de la représentation des
nombres à virgule flottante. En effet, comme les cellules mémoires de l'ordinateur sont limitées dans leur taille, le
réel x = 1 / 3 est représenté par 0.3333333 et donc le réel y = 3 * x est plutôt 0.9999999 et non pas 1 !
A cet effet, on se propose de représenter la fraction 1/3 comme deux entiers distincts (1 et 3), et 3 comme la
fraction 3/1. Ensuite, une multiplication de ces deux fractions donnerait exactement 1 et non pas plus ou moins 1.
1/2
La classe Fraction est définie comme suit :
Publicité
class Fraction {
private:
int numer; // numérateur
int denom; // dénominateur
public:
Fraction(int num=1, int den=1) : numer(num), denom(den)
{ if (denom) == 0 ) denom = 1; }
};
Exercice n°3 (8,5 pts) : (les questions se trouvent dans les pages de 5/8 à 8/8)
On se propose d’écrire en C++ une classe représentant un ensemble d’entiers et de l’utiliser dans un petit
exemple : le calcul des nombres premiers par le crible d’Eratosthène.
Pour trouver tous les nombres premiers de 2 à MAX, le principe du crible d’Eratosthène est le suivant :
1. Construire un ensemble contenant tous les entiers de 2 à MAX;
2. Extraire le plus petit élément de cet ensemble car c’est un nombre premier et l’afficher;
3. Enlever de cet ensemble tous les multiples de ce nombre premier ;
4. Continuer en 2 jusqu’à ce que l’ensemble soit vide.
Pour simplifier, on définira seulement les opérations sur les ensembles qui sont utiles pour le crible
d’Eratosthène : ajouter (add) un élément, supprimer (del) un élément, savoir si un élément est présent
(estPresent) ou non, savoir si l’ensemble est vide (estVide) ou non, donner le plus petit élément (plusPetit) de
l’ensemble. On ne considérera donc pas les opérations sur les ensembles telles que l’union, l’intersection,
l’inclusion, etc.
Un ensemble contient des éléments uniques et on suppose que les éléments sont placés dans un ordre
quelconque. On se propose d’implémenter un ensemble par une liste chaînée. La figure suivante vous aidera à
comprendre la structure de l’implémentation.
Après l’invocation de la méthode “add(4)” l’ensemble reste le même car l’ensemble contient déjà “4”.
Après l’invocation de la méthode “add(3)” l’ensemble se réarrange comme suit (on suppose que l’ajout se fait en
début de liste):
Un exemple d’usage des méthodes de la classe Ensemble.
Ensemble set;
set.add(1);
set.add(8);
set.add(2);
while ( ! set.estVide() )
{
int ppe = set.plusPetit();
cout << ppe << endl ;
set.del(ppe);
}
Le programme affiche :
1
Publicité
2
8
2/2
Devoir « Programmation Orientée Objets » - Avril 2011 / ENSI
Formulaire de réponse (1/2)
Nom …………………………… Prénom …………………………….Classe :……………………..
20
Exercice n°1 (6 pts):
Pour chacune des instructions suivantes appartenant à un même bloc, donner s’il y a lieu : l’affichage
produit et éventuellement la ou les erreurs dans la gestion de la mémoire (violation et/ou fuite) en expliquant
les causes.
A a1;
a1.afficher();
A a2(5);
a1 = a2;
a1.afficher();
A a3 = a2;
a3.afficher();
1/8
B b1;
B b2(2);
b1.afficher();
b1.f(a2);
Fin du bloc
Exercice n°2 (5,5 pts) :
1) Définir et implémenter les opérateurs de multiplication et d’addition de deux fractions. N’oubliez pas de mettre
la fraction en forme réduite (la forme réduite de la fraction 40/60 et 2/3).
Remarque : Vous pouvez utiliser la fonction « int pgcd(int a, int b) » qui retourne le pgcd de deux entiers.
2/8
2) On souhaite multiplier une fraction par un entier et on souhaite multiplier un entier par une fraction. Définir et
implémenter les deux opérateurs de multiplication en tenant compte de l’ordre des arguments. N’oubliez pas de
mettre le résultat sous forme réduite.
3) Définir et implémenter les opérateurs d’égalité et de non égalité de deux fractions.
4) On se propose de faire une affectation de fractions (exple F1 = F2). Est-il nécessaire de redéfinir cet opérateur ?
justifier votre réponse.
3/8
5) Maintenant qu’on dispose de la classe Fraction telle qu’elle a été définie dans l’énoncé et les opérateurs définis
dans les questions précédentes :
a. Donner le corps du programme qui permet de calculer la fraction F3 = 2 * F2 + F1 (sachant que F1 = 1/2
et F2 = 2/3) et d’indiquer si F3 est égale ou non à la fraction 5/6.
Publicité
b. Donner le corps du programme qui permet de calculer la suite suivante (en utilisant impérativement la
classe Fraction):
Un = 1 + 1/2 + 1/3 + 1/4 + …. + 1/100
4/8
Devoir « Programmation Orientée Objets » - Avril 2011 / ENSI
Formulaire de réponse (2/2)
Nom …………………………… Prénom …………………………….Classe :……………………..
Exercice n°3 (8,5 pts):
La structure Noeud est définie comme suit :
struct Noeud {
Noeud * next;
int valeur;
};
1) Concernant la classe Ensemble et sachant qu’on ne souhaite manipuler qu’une seule instance de la
classe Ensemble, dire s’il est nécessaire de définir ou pas un constructeur par défaut (sans arguments),
un constructeur de copie, un destructeur, un opérateur d’affectation. Justifier brièvement chaque
réponse.
2) Donner la déclaration (l’interface) de la classe Ensemble qui décrit un ensemble d’entiers.
class Ensemble
{
private:
public:
};
5/8
3) Donner l’implémentation de toutes les méthodes que vous avez définies dans la question précédente.
6/8
7/8
4) Ecrire un programme principal qui saisit un entier n ≥ 2 et moyennant la classe Ensemble définie
précédemment (bien sûr !):
• Remplit l’ensemble set par les entiers de 2 à n
• Calcule et affiche les nombres premiers ≤ n en utilisant le principe du crible d’Eratosthène.
void main( )
{
Ensemble set;
}
8/8