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