Examen - Master 1 - UPMC

Transcription

Examen - Master 1 - UPMC
Université Pierre et Marie Curie
Période 2 - 2012/2013
Master M1 "Mathématiques et Applications"
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
2
# include < stdlib .h >
# include < stdio .h >
puis définir une fonction f (destinée à comparer 2 double) compatible avec le pointeur compar, par exemple :
2
4
6
int f ( const void * a , const void * b ) {
double x = *(( const double *) a );
double y = *(( const double *) b );
if ( x < y ) return -1;
if ( x > y ) return 1;
return 0;
}
et enfin écrire la fonction principale :
2
4
6
8
int main ( void ) {
double tab [] = { 1 , 2.718 , 3.142 , 10 };
double x = 4; // ou n ’ importe quelle valeur
double * r = bsearch (& x , tab , 4 , sizeof ( double ) , f );
if ( r == NULL )
printf ( " la valeur \% g n ’ est pas dans le tableau \ n " , x );
return 0;
};
3. struct complex {
double re ;
double im ;
2
4
};
typedef struct complex complex ;
4. int compare_module ( const void * a , const void * b ) {
const complex * x = ( const complex *) a ;
double module_x = x - > re *x - > re + x - > im *x - > im ;
const complex * y = ( const complex *) b ;
double module_y = y - > re *y - > re + y - > im *y - > im ;
if ( module_x < module_y ) return -1;
if ( module_x > module_y ) return 1;
return 0;
2
4
6
8
}
5. Avec les mêmes en-têtes que la question 2 :
2
4
6
8
int main ( void ) {
complex a = {0 , 1};
complex b = {1 , 0.5};
complex c = {1 , 2};
complex d = {4 , 0};
complex tab [] = {a , b , c , d };
complex x = {1 , 0.5};
complex * s = bsearch (& x , tab , 4 , sizeof ( complex ) , compare_module );
1
if ( s == NULL )
printf ( " pas dans le tableau \ n " );
return 0;
10
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.
2
4
6
8
10
12
14
16
18
20
22
24
26
Interpol :: Interpol ( Interpol const & o ) : n ( o . n ) {
points_x = new double [ n ];
points_y = new double [ n ];
poids = new double [ n ];
for ( int i = 0; i < n ; ++ i ) {
points_x [ i ] = o . points_x [ i ];
points_y [ i ] = o . points_y [ i ];
poids [ i ] = o . poids [ i ];
}
};
Interpol & Interpol :: operator =( Interpol const & o ) {
if ( this == & o ) return * this ;
delete [] points_x ;
delete [] points_y ;
delete [] poids ;
n = o.n;
points_x = new double [ n ];
points_y = new double [ n ];
poids = new double [ n ];
for ( int i = 0; i < n ; ++ i ) {
points_x [ i ] = o . points_x [ i ];
points_y [ i ] = o . points_y [ i ];
poids [ i ] = o . poids [ i ];
}
return * this ;
};
28
30
32
Interpol ::~ Interpol () {
delete [] points_x ;
delete [] points_y ;
delete [] poids ;
};
3. class Interpol {
public :
Interpol ( std :: string nom_fichier , int n );
// il faut redefinir le constructeur de copie :
Interpol ( Interpol const & o );
// l ’ operateur d ’ affectation
Interpol & operator =( Interpol const & o );
// et le destructeur
~ Interpol ();
// les points x_k etant ordonnes on ajoute les min et max ( const )
double min () const { return points_x [0]; }
double max () const { return points_x [n -1]; }
virtual double operator ()( double x ) const = 0;
protected :
int n ;
double * points_x , * points_y , * poids ;
2
4
6
8
10
12
14
16
};
4. class InterpolLin : public Interpol {
2
public :
InterpolLin ( std :: string nom , int n );
2
double operator ()( double x ) const ;
4
};
6
8
10
InterpolLin :: InterpolLin ( std :: string nom , int n ) : Interpol ( nom , n ) {
for ( int i = 0; i < n -1; i ++) {
poids [ i ] = ( points_y [ i +1] - points_y [ i ]) / ( points_x [ i +1] - points_x [ i ]);
}
};
5. double InterpolLin :: operator ()( double x ) const {
for ( int i = 0; i < n -1; i ++) {
if ( x >= points_x [ i ] && x <= points_x [ i +1])
return points_y [ i ] + poids [ i ] * ( x - points_x [ i ]);
}
return x < points_x [0] ? points_y [0] : points_y [n -1];
2
4
6
};
6. class InterpolPoly : public Interpol {
public :
InterpolPoly ( std :: string nom , int n );
double operator ()( double x ) const ;
2
4
};
6
8
10
12
14
16
18
20
InterpolPoly :: InterpolPoly ( std :: string nom , int n ) : Interpol ( nom , n ) {
double tmp [ n ];
// on initialise le tableau a ( suppose deja alloue )
for ( int i = 0; i < n ; i ++)
poids [ i ] = points_y [ i ];
for ( int i = 1; i < n ; i ++) {
// on travaille sur un tableau temporaire tmp
for ( int j = i ; j < n ; j ++)
tmp [ j ] = ( poids [ j ] - poids [j -1]) / ( points_x [ j ] - points_x [j - i ]);
// puis on le recopie
for ( int j = i ; j < n ; j ++)
poids [ j ] = tmp [ j ];
}
};
7. double InterpolPoly :: operator ()( double x ) const {
// une reecriture du polynome P permet une evaluation facile :
double result = poids [n -1];
for ( int i = n -2; i >= 0; i - -)
result = poids [ i ] + ( x - points_x [ i ])* result ;
return result ;
2
4
6
};
3