« C pointeurs/Pointeurs de fonctions » : différence entre les versions

Contenu supprimé Contenu ajouté
Aucun résumé des modifications
Page blanchie
Ligne 1 :
{{Chapitre
| niveau = 14
| idfaculté = informatique
| numéro = 2
| précédent = [[../Pointeurs de fichiers/]]
| suivant = [[../ Tableau de pointeurs de fonctions/]]
}}
 
 
== Introduction ==
 
* En langage C, le nom d'une fonction est un pointeur.
* On peut l'utiliser comme '''argument''' dans l'appel d'une fonction.
* Exemple : <tt>G_plot('''f''');</tt> (<tt>f(x)</tt> étant une fonction)
 
 
Un pointeur de fonction doit avoir le même prototype que la fonction pointée.
 
* Pour la fonction f(x) :
<source lang="c">
double f (double x) {return( pow(x,2.));}
double (*P_f)(double x)
</source>
 
 
* Pour la fonction g(x,y) :
<source lang="c">
double g (double x,double y) {return(x*y;}
double (*P_g)(double x,double y)
</source>
 
 
Pour appeler la fonction, nous utiliserons cette méthode :
 
* Pour la fonction f(x) :
<source lang="c">
((*P_f)(a)) /* corresponds à un appel de fonction de forme f(a). */
</source>
 
 
* Pour la fonction g(x,y) :
<source lang="c">
((*P_g)(a,b)) /* corresponds à un appel de fonction de forme g(a,b). */
</source>
 
 
Remarque :
* f et g sont des pointeurs
* f() et g() sont des fonctions.
 
 
* <tt>double (*P_f)(double x)</tt> c'est une déclaration de pointeur de fonction.
* <tt>P_f</tt> c'est le pointeur.
* <tt>((*P_f)())</tt> ou <tt>(*P_f)()</tt> c'est un appel à une fonction.
 
 
== Exemples graphiques (avec Gnuplot) ==
 
 
=== Dessiner deux fonctions successivement ===
* La fonction Gplt() dessine f(x) et g(x).
 
<source lang="c">
/* ------------------------------ */
/* Save as c01.c */
/* ------------------------------ */
#include <stdio.h>
#include <math.h>
 
/* ------------------------------ */
double f(double x) {return( pow(x,2.));}
double g(double x) {return(2.0*x + 3.0);}
 
/* ------------------------------ */
void G_plt(
double (*P_f)(double x)
)
{
FILE *fp = fopen("data","w");
double a = -5.0;
 
for(; a <= 5.0; a += 0.3)
fprintf(fp," %6.3f %6.3f\n",a,((*P_f)(a)));
fclose(fp);
}
 
/* ------------------------------ */
int main(void)
{
printf(" Type: plot \"data\" ");
G_plt(f);
getchar();
 
printf(" Type: plot \"data\" ");
G_plt(g);
 
printf("\n\n Press return to continue.\n");
getchar();
 
return 0;
}
</source>
 
 
=== Dessiner deux fonctions successivement (2) ===
 
La fonction G_plot() dessine la fonction (data) et la chaîne de caractères.
 
 
<source lang="c">
/* ------------------------------ */
/* Save as c02.c */
/* ------------------------------ */
#include <stdio.h>
#include <math.h>
 
/* ------------------------------ */
double f(double x){return(cos(x));}
char feq[] = "cos(x)";
 
/* ------------------------------ */
double g(double x){return(sin(x));}
char geq[] = "sin(x)";
 
/* ------------------------------ */
int G_plot(
double (*P_f)(double x),
char Feq[])
{
FILE *fp;
double a = -5.0;
 
fp = fopen("data","w");
for(; a <= 5.0; a+=.2)
fprintf(fp," %6.3f %6.3f\n",a,((*P_f)(a)));
fclose(fp);
 
fp = fopen("a_main.plt","w");
fprintf(fp,"# Gnuplot file : load \"a_main.plt\" \n"
" set zeroaxis\n"
" plot \"data\",\\\n"
" %s\n"
" reset",Feq);
fclose(fp);
 
return 0;
}
 
/* ------------------------------ */
int main(void)
{
printf(" load \"a_main.plt\" with gnuplot ");
G_plot(f,feq);
getchar();
 
printf(" load \"a_main.plt\" with gnuplot ");
G_plot(g,geq);
 
printf("\n\n Press return to continue.\n");
getchar();
 
return 0;
}
</source>
 
Résultat après le premier appel de G_plot():
 
<source lang="gnuplot">
# Gnuplot file : load "a_main.plt"
set zeroaxis
plot "data",\
cos(x)
reset
</source>
 
Résultat après le deuxième appel de G_plot():
 
<source lang="gnuplot">
# Gnuplot file : load "a_main.plt"
set zeroaxis
plot "data",\
sin(x)
reset
</source>
 
 
== Exemple numérique ==
 
Passer des pointeurs de fonctions à une fonction.
 
 
=== Les fonctions f‘ et f‘‘ ===
 
* Calculer la dérivée première et seconde d'une fonction.
 
 
<source lang="c">
/* ------------------------------ */
/* Save as c03.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";
 
/* ------------------------------
f'(a) = f(a+h) - f(a-h)
-------------
2h
------------------------------ */
double Dx_1(
double (*P_f)(double x),/* Declaration de pointeur de fonction */
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 Dx_2(
double (*P_f)(double x),/* Declaration de pointeur de fonction */
double a,
double h
)
{
return( (((*P_f)(a+h))-2*((*P_f)(a))+((*P_f)(a-h))) / (h*h) );
}
 
/* ------------------------------ */
int main(void)
{
double x = 2.;
double h = 0.001;
 
printf("\n\n");
 
printf(" f(%.3f) = %.3f \n",x,f(x) );
printf(" f'(%.3f) = %.3f \n",x,Dx_1(f,x,h));
printf("f''(%.3f) = %.3f \n",x,Dx_2(f,x,h));
 
printf("\n\n");
 
printf(" g(%.3f) = %.3f \n",x,g(x) );
printf(" g'(%.3f) = %.3f \n",x,Dx_1(g,x,h));
printf("g''(%.3f) = %.3f \n",x,Dx_2(g,x,h));
 
printf("\n\n Press return to continue.");
 
getchar();
 
return 0;
}
</source>
 
 
Résultat :
 
f(2.000) = 4.000
f‘(2.000) = 4.000
f‘‘(2.000) = 2.000
.
g(2.000) = 0.082
g‘(2.000) = 1.341
g‘‘(2.000) = 0.398
.
Press return to continue.
 
 
=== La fonction FoG ===
 
* Ici on passe les deux fonctions f et g à la fonction FoG().
* La même fonction peut calculer gof, fog et fof...
 
 
<source lang="c">
/* ------------------------------ */
/* 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(2.0*x + 3.0);}
char geq[] = "2.0*x + 3.0";
 
/* ------------------------------ */
double FoG(
double (*P_F)(double x),/* Pointeur pour la premiere fonction */
double (*P_G)(double x),/* Pointeur pour la deuxieme fonction */
double a
)
{
return((*P_F)( ((*P_G)(a))) );
}
 
/* ------------------------------ */
int main(void)
{
double a = 2.0;
 
printf(" f : x-> %s\n", feq);
printf(" g : x-> %s\n", geq);
printf(" \n\n");
 
printf(" f(g(%.0f)) = %6.1f\n", a, FoG(f,g,a));
printf(" g(f(%.0f)) = %6.1f\n", a, FoG(g,f,a));
printf(" f(f(%.0f)) = %6.1f\n", a, FoG(f,f,a));
 
printf("\n\n Press return to continue.\n");
getchar();
 
return 0;
}
</source>
 
Résultat :
 
f : x-> x**2
g : x-> 2.0*x + 3.0
.
f(g(2)) = 49.0
g(f(2)) = 11.0
f(f(2)) = 16.0
.
Press return to continue.
 
 
==== Version main() avec sortie dans le fichier "list.txt" ====
 
 
* Déclarer le pointeur de fichiers.
** FILE *fp;
* Ouvrir le fichier.
** fp = fopen("list.txt","w");
* Fermer le fichiers
** fclose(fp);
* Remplacer tout les '''printf(''' par '''fprintf(fp,'''
** fprintf(fp,
 
 
<source lang="c">
/* ------------------------------ */
int main(void)
{
FILE *fp;
 
double a = 2.0;
 
fp = fopen("list.txt","w");
fprintf(fp," f : x-> %s\n", feq);
fprintf(fp," g : x-> %s\n", geq);
fprintf(fp," \n\n");
 
fprintf(fp," f(g(%.0f)) = %6.1f\n", a, FoG(f,g,a));
fprintf(fp," g(f(%.0f)) = %6.1f\n", a, FoG(g,f,a));
fprintf(fp," f(f(%.0f)) = %6.1f\n", a, FoG(f,f,a));
 
fclose(fp);
 
printf("\n\n Press return to continue.\n");
getchar();
 
return 0;
}
/* ------------------------------ */
</source>
 
 
{{Bas de page
| idfaculté = informatique
| précédent = [[../Pointeurs de fichiers/]]
| suivant = [[../Tableau de pointeurs de fonctions/]]
}}