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 2012 - Corrigé
Deux heures - Sans document.

Exercice 1 (Recherche dichotomique en C)


1. Le type const void * est le type d’un pointeur générique sur valeur constante, c’est à dire le pointeur compatible
avec tout autre pointeur et dont la valeur à cette adresse ne peut être modifiée.
L’argument compar est un pointeur sur une fonction prenant deux arguments (duex pointeurs génériques sur
valeur constante) et renvoyant un entier.
2. Il y a plusieurs étapes pour écrire ce programme. Il faut d’abord donner les en-têtes à inclure
# include < stdlib .h >
2 # include < stdio .h >
puis définir une fonction f (destinée à comparer 2 double) compatible avec le pointeur compar, par exemple :
int f ( const void * a , const void * b ) {
2 double x = *(( const double *) a );
double y = *(( const double *) b );
4 if ( x < y ) return -1;
if ( x > y ) return 1;
6 return 0;
}
et enfin écrire la fonction principale :
int main ( void ) {
2 double tab [] = { 1 , 2.718 , 3.142 , 10 };
double x = 4; // ou n ’ importe quelle valeur
4 double * r = bsearch (& x , tab , 4 , sizeof ( double ) , f );
if ( r == NULL )
6 printf ( " la valeur \% g n ’ est pas dans le tableau \ n " , x );
return 0;
8 };

3. struct complex {
2 double re ;
double im ;
4 };
typedef struct complex complex ;

4. int compare_module ( const void * a , const void * b ) {


2 const complex * x = ( const complex *) a ;
double module_x = x - > re *x - > re + x - > im *x - > im ;
4 const complex * y = ( const complex *) b ;
double module_y = y - > re *y - > re + y - > im *y - > im ;
6 if ( module_x < module_y ) return -1;
if ( module_x > module_y ) return 1;
8 return 0;
}

5. Avec les mêmes en-têtes que la question 2 :


int main ( void ) {
2 complex a = {0 , 1};
complex b = {1 , 0.5};
4 complex c = {1 , 2};
complex d = {4 , 0};
6 complex tab [] = {a , b , c , d };
complex x = {1 , 0.5};
8 complex * s = bsearch (& x , tab , 4 , sizeof ( complex ) , compare_module );

1
if ( s == NULL )
10 printf ( " pas dans le tableau \ n " );
return 0;
12 }

Exercice 2 (Interpolation en C++)


1. La classe est appelée classe abstraite car la méthode operator() est une méthode virtuelle pure.
2. Les 3 méthodes à redéfinir sont le constructeur de copie, l’opérateur d’affectation et le destructeur.
Interpol :: Interpol ( Interpol const & o ) : n ( o . n ) {
2 points_x = new double [ n ];
points_y = new double [ n ];
4 poids = new double [ n ];
for ( int i = 0; i < n ; ++ i ) {
6 points_x [ i ] = o . points_x [ i ];
points_y [ i ] = o . points_y [ i ];
8 poids [ i ] = o . poids [ i ];
}
10 };

12 Interpol & Interpol :: operator =( Interpol const & o ) {


if ( this == & o ) return * this ;
14 delete [] points_x ;
delete [] points_y ;
16 delete [] poids ;
n = o.n;
18 points_x = new double [ n ];
points_y = new double [ n ];
20 poids = new double [ n ];
for ( int i = 0; i < n ; ++ i ) {
22 points_x [ i ] = o . points_x [ i ];
points_y [ i ] = o . points_y [ i ];
24 poids [ i ] = o . poids [ i ];
}
26 return * this ;
};
28

Interpol ::~ Interpol () {


30 delete [] points_x ;
delete [] points_y ;
32 delete [] poids ;
};

3. class Interpol {
2 public :
Interpol ( std :: string nom_fichier , int n );
4 // il faut redefinir le constructeur de copie :
Interpol ( Interpol const & o );
6 // l ’ operateur d ’ affectation
Interpol & operator =( Interpol const & o );
8 // et le destructeur
~ Interpol ();
10 // les points x_k etant ordonnes on ajoute les min et max ( const )
double min () const { return points_x [0]; }
12 double max () const { return points_x [n -1]; }
virtual double operator ()( double x ) const = 0;
14 protected :
int n ;
16 double * points_x , * points_y , * poids ;
};

4. class InterpolLin : public Interpol {


2 public :
InterpolLin ( std :: string nom , int n );

2
4 double operator ()( double x ) const ;
};
6

InterpolLin :: InterpolLin ( std :: string nom , int n ) : Interpol ( nom , n ) {


8 for ( int i = 0; i < n -1; i ++) {
poids [ i ] = ( points_y [ i +1] - points_y [ i ]) / ( points_x [ i +1] - points_x [ i ]);
10 }
};

5. double InterpolLin :: operator ()( double x ) const {


2 for ( int i = 0; i < n -1; i ++) {
if ( x >= points_x [ i ] && x <= points_x [ i +1])
4 return points_y [ i ] + poids [ i ] * ( x - points_x [ i ]);
}
6 return x < points_x [0] ? points_y [0] : points_y [n -1];
};

6. class InterpolPoly : public Interpol {


2 public :
InterpolPoly ( std :: string nom , int n );
4 double operator ()( double x ) const ;
};
6

InterpolPoly :: InterpolPoly ( std :: string nom , int n ) : Interpol ( nom , n ) {


8 double tmp [ n ];
// on initialise le tableau a ( suppose deja alloue )
10 for ( int i = 0; i < n ; i ++)
poids [ i ] = points_y [ i ];
12 for ( int i = 1; i < n ; i ++) {
// on travaille sur un tableau temporaire tmp
14 for ( int j = i ; j < n ; j ++)
tmp [ j ] = ( poids [ j ] - poids [j -1]) / ( points_x [ j ] - points_x [j - i ]);
16 // puis on le recopie
for ( int j = i ; j < n ; j ++)
18 poids [ j ] = tmp [ j ];
}
20 };

7. double InterpolPoly :: operator ()( double x ) const {


2 // une reecriture du polynome P permet une evaluation facile :
double result = poids [n -1];
4 for ( int i = n -2; i >= 0; i - -)
result = poids [ i ] + ( x - points_x [ i ])* result ;
6 return result ;
};

Vous aimerez peut-être aussi