Aller au contenu

Mathc gnuplot/Tableau de pointeurs de fonctions

Un livre de Wikilivres.
Mathc gnuplot
Mathc gnuplot
Mathc gnuplot
Sommaire

I - Dessiner

Fichiers h partagés :

Application :

II - Animer

Application :

III - Géométrie de la tortue standard

Application :

IV - Géométrie de la tortue vectorielle

Application :

Annexe


Nous avons des fonctions semblables. Nous voulons les associer pour pouvoir les manipuler dans des boucles. Nous allons créer un tableau de pointeurs de fonctions.

Le tableau de pointeurs de fonctions doit être déclaré avec un prototype de la même forme que celui des fonctions.


Tableau de pointeurs de fonctions

[modifier | modifier le wikicode]

Les fonctions trigonométriques

[modifier | modifier le wikicode]

Nous allons utiliser les fonctions trigonométriques du C.


Déclaration du tableau

[modifier | modifier le wikicode]
double (*TrigF[6])(double x) = {cos,sin,tan,atan,asin,acos};
  • Toutes les fonctions ont la même forme : double fonction(double).
  • Le tableau à la même forme que les fonctions : double tableau(double).
  • Il y a six fonctions : cos, sin, tan, atan, asin, acos.


Exemple d'un appel

[modifier | modifier le wikicode]
   cos(.5) == TrigF[0](.5)


Exemple à tester

[modifier | modifier le wikicode]
c01.c
Exemple à tester
/* ------------------------------ */
/* Save as c01.c                  */
/* ------------------------------ */
#include    <stdio.h>
#include     <math.h>
/* ------------------------------ */
int main(void)
{
double (*TrigF[6])(double x) = {cos,sin,tan,atan,asin,acos};

double x= .5;
int    i=  0;

 printf(" Nous avons declare un tableau "
        " de pointeurs de fonctions.\n  "
        " J'ai utilise ici les fonctions predefinie du c.\n");

  
  printf("       cos(%.1f)  = %.3f  \n",  x,     cos(x));
  printf(" TrigF[%d](%.1f)) = %.3f\n\n",i,x,TrigF[i](x));

 printf(" Press return to continue");
 getchar();

 return 0;
}


  • Créez un tableau de valeurs des fonctions trigonométriques.
  • Imprimez le résultat dans cette ordre (sin,cos,tan,acos,asin,atan)
  • Pour .1 <= x <+ .5


Avec le résultat dans un fichier

[modifier | modifier le wikicode]
c02.c
Avec le résultat dans un fichier
/* ------------------------------ */
/* Save as c02.c                  */
/* ------------------------------ */
#include    <stdio.h>
#include     <math.h>
/* ------------------------------ */
int main(void)
{
FILE   *fp = fopen("list.txt","w");

double (*TrigF[6])(double x) = {atan,asin,acos,tan,cos,sin};

int    i= 6; 
double x= .1;

fprintf(fp,"   x || sin    cos    tan    acos   asin   atan \n");

     for(;x<=.5;x+=.1)
        {
         fprintf(fp," %.1f ||",x);
         for(i=6;i;)
            fprintf(fp," %.3f ",TrigF[--i](x));
         fprintf(fp,"\n");
        }

 fclose(fp);

 printf("\n\n Ouvrir le fichier list.txt\n");
 getchar();

 return 0;
}


Le résultat :

  x || sin    cos    tan    acos   asin   atan 
0.1 || 0.100  0.995  0.100  1.471  0.100  0.100 
0.2 || 0.199  0.980  0.203  1.369  0.201  0.197 
0.3 || 0.296  0.955  0.309  1.266  0.305  0.291 
0.4 || 0.389  0.921  0.423  1.159  0.412  0.381 
0.5 || 0.479  0.878  0.546  1.047  0.524  0.464 


Remarques :

  • Attention à l'ordre des fonctions dans la déclaration du tableau.
  • double (*TrigF[6])(double x) = {atan,asin,acos,tan,cos,sin};


Au démarrage :

  • La décrémentation se fait dans le tableau. TrigF[--i](x)
  • i=6 entre dans le tableau.
  • 6 est décrémenté -> 5 (avant l'appel de la fonction --i)
  • La sixième fonction est appelée (Sin).
  • La numéro cinq. :)


Au final :

  • Il entre UN dans le tableau.
  • UN est décrémenté -> 0
  • La première fonction est appelée (atan).
  • La numéro zéro. :))


  • i est égal à zéro en rentrant dans la boucle.
  • Le cycle est cassé. :(


Avec le résultat à l'écran

[modifier | modifier le wikicode]
c03.c
Avec le résultat à l'écran
/* ------------------------------ */
/* Save as c03.c                  */
/* ------------------------------ */
#include    <stdio.h>
#include     <math.h>
/* ------------------------------ */
int main(void)
{
double (*TrigF[6])(double x) = {atan,asin,acos,tan,cos,sin};

int    i= 6;
double x= .1;

     for(;x<=.5;x+=.1)
       {
         printf("\n");
         for(i=6;i;) printf(" %.3f ",TrigF[--i](x));
       }

 printf("\n\n Press return to continue.\n");
 getchar();

 return 0;
}


Les fonctions f‘ et f‘‘

[modifier | modifier le wikicode]

Nous voulons créer la fonction Derivate pour calculer les dérivées première et seconde d'une fonction en utilisant un tableau de pointeurs de fonctions.

Voir listing en fin de page.


Déclaration du tableau

[modifier | modifier le wikicode]
double (*Derivate[3])(double (*P_f)(double x),double a,double h) = {fx,Df_x,Df_xx};
  • Toutes les fonctions (fx,Df_x,Df_xx) ont la même forme : double fonction(double (*P_f)(double x) double double).
  • Le tableau a la même forme que les fonctions : double tableau(double (*P_f)(double x) double double).

Il y a trois fonctions. (0,1,2)= {fx, Df_x, Df_xx}. La fonction fx donne f.

  • Supprimez cette fonction et travaillez sur deux fonctions.
  • Réfléchissez.


Exemple d'un appel

[modifier | modifier le wikicode]
     f(x) == Derivate[0](f,x,0.)


  • Derivate[0] donne f(x).
  • Voir la fonction fx() la première fonction du tableau.
  • h = 0 dans cet appel parce qu'il n'est pas utilisé (voir code de fx())


Exemple à tester

[modifier | modifier le wikicode]
c04.c
Exemple à tester
/* ------------------------------ */
/* Save as c04.c                  */
/* ------------------------------ */
#include    <stdio.h>
#include     <math.h>
/* ------------------------------ */
/* ------------------------------ */
double f(double x){return( pow(x,2.));}
/* ------------------------------ */
char  feq[] = "x**2";
/* ------------------------------ */
/* ------------------------------ */
double g(double x){return(
 pow(cos(x),2.)+sin(x)+x-3);}
/* ------------------------------ */
char  geq[] = "cos(x)**2+sin(x)+x-3";
/* ------------------------------ */
/* ------------------------------ */
double fx(
double (*P_f)(double x),
double a,
double h
)
{
 return( ((*P_f)(a)) );
}
/* ------------------------------
 f'(a) = f(a+h) - f(a-h)
          -------------
              2h
   ------------------------------ */
double Df_x(
double (*P_f)(double x),
double a,
double h
)
{
 return( ( ((*P_f)(a+h))-((*P_f)(a-h)) ) / (2.*h) );
}
/* -----------------------------
 f''(a) = f(a+h) - 2 f(a) + f(a-h)
           ----------------------
                     h**2
   ------------------------------- */
double Df_xx(
double (*P_f)(double x),
double a,
double h
)
{
 return( (((*P_f)(a+h))-2*((*P_f)(a))+((*P_f)(a-h))) / (h*h) );
}
/* ------------------------------ */
int main(void)
{
double (*Derivate[3])(double (*P_f)(double x),
                      double a,
                      double h) = {fx,Df_x,Df_xx};
double a = 2;
double h = 0.001;

printf("\n\n");

printf("  f(%.3f) = %.3f = %.3f \n",a,      f(a),  Derivate[0](f,a,0));
printf(" f'(%.3f) = %.3f = %.3f \n",a,Df_x (f,a,h),Derivate[1](f,a,h));
printf("f''(%.3f) = %.3f = %.3f \n",a,Df_xx(f,a,h),Derivate[2](f,a,h));

printf("\n\n");

printf("  g(%.3f) = %.3f = %.3f \n",a,      g(a),  Derivate[0](g,a,0));
printf(" g'(%.3f) = %.3f = %.3f \n",a,Df_x (g,a,h),Derivate[1](g,a,h));
printf("g''(%.3f) = %.3f = %.3f \n",a,Df_xx(g,a,h),Derivate[2](g,a,h));

 printf("\n\n Press return to continue.");
 getchar();

 return 0;
}