CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[c] tableau de fonctions

dnob700
dnob700
Niveau 10
22 octobre 2005 à 16:56:00

Je viens de lire qu´il est impossible de déclarer des tableau de fonctions en C ?

Enfin, on peut, mais avec certaines restriction.
Par exemple il est impossible de déclarer :

double (*f)(double);

alors, double (*f[])(double) semble fonctionner même si je n´en comprend pas le sens, mais ça empêche d´utiliser un simple pointeur sur une fonction comme un tableau de dimensions 1.

J´explique mon problème : j´écris une fonction qui trace des fonctions mathématiques.

j´aurais voulu avoir un prototype de ce genre :
tracer(double (*f[])(double), int nombre, double xmin, double xmax)
{
int i;
double x;
for (i=0;i<nb;i++)
for (x=xmin;x<xmax;x++)
pixel(x,(f[i])(x));
}

et appeler la fonction par exemple avec :
tracer(&cos,1,xmin,xmax);
si par exemple je n´ais qu´une seul fonction à tracer.

Mais, si la fonction se compile sans problème, le compilo n´aime pas du tout ma manière de l´appeler, et je n´ais pas réussi à trouver de méthode qui fonctionne.

Donc si quelqu´un pouvait m´éclairer sur le sujet, je lui en serait reconnaissant.

merci.

kufa
kufa
Niveau 9
24 octobre 2005 à 15:48:15

Tiens, du code c qui fait ca:

(http://rafb.net/paste/results/jaOG5p16.html)

  1. include <stdio.h>
  2. include <math.h>

typedef double (*math_call)(double);

void tracer( math_call f, double xmin, double xmax, double increment )
{
double x;
for( x = xmin; x <= xmax; x += increment )
{
double valeur = f( x );
printf( "%lf : %lf\n", x, valeur );
}
}

double my_square( double nombre )
{
return nombre * nombre;
}

int main()
{
math_call myCos = cos;
math_call mySin = sin;
math_call mySquare = my_square;

tracer( mySquare, 0, 5, 1 );
tracer( myCos, 0, 3.14, 1 );
return 0;
}

dnob700
dnob700
Niveau 10
24 octobre 2005 à 16:16:54

Merci, mais ceci j´avais réussi à l´obtenir, ce qui je ne trouve pas c´est comment passer un tableau de fonction à la fonction Tracer.

De manière à ce qu´on puisse l´appeler aussi bien avec un tableau de fonctions, qu´avec juste une seul fonction comme on le fzit avec des tableau de n´importe quoi usuellement.

En gros qu´on puisse écrire :

double (*f[3])(double)={&sin,&cos,&tan};
Tracer(f,3);
Tracer(&sin,1)
//Les fonctions trigo ne sont pas de très bon exemple car elles sont surchargées, mais supposons qu´elles ne le sont pas.

On peut le faire pour un tableau d´autre chose que de fonction, mais ça semble impossible avec des fonctions.

Altonfrere
Altonfrere
Niveau 10
24 octobre 2005 à 20:53:44

et ca ?

  1. include <stdio.h>
  2. include <math.h>

typedef double (*math_call)(double);

void tracer( math_call *f, double xmin, double xmax, double increment )
{
double x;
for( x = xmin; x <= xmax; x += increment )
{
double valeur = f[0]( x );
printf( "%lf : %lf\n", x, valeur );
}
}

double my_square( double nombre )
{
return nombre * nombre;
}

int main()
{
math_call func[3] = { cos, sin, my_square };

tracer( func, 0, 3.14, 1 );
return 0;
}

[LoCkLeSs]
[LoCkLeSs]
Niveau 10
24 octobre 2005 à 21:03:45

Hoy Altonfrère est de retour :)

Altonfrere
Altonfrere
Niveau 10
24 octobre 2005 à 21:43:01

et oui :)

MrGoTo
MrGoTo
Niveau 8
24 octobre 2005 à 22:50:32

Altonfrere !! !!!!!!!!!!!!!
On te pensait tous mort !
Comment ça va, vieille branche !

dnob700
dnob700
Niveau 10
24 octobre 2005 à 23:37:35

Je sais que je suis chiant, mais ça aussi finalement j´ai réussi à le faire (même si je n´ais pas réussi à le faire sans typedef).

Toujours est-il que ça ne permet pas d´écrire ça :
tracer((math_call*)&my_square, 0, 3.14, 1 );
Enfin, là ça compile, mais ça plante irrémédiablement lors de l´appel de la fonction f dans le corp de la fonction Tracer.

Mais c´est un truc que je ne comprend pas car il semble que pour le compilo (my_square) et &my_square soit absolument équivalent ce qui explique qu´il ne veuille pas prendre &my_square pour un tableau à une dimension.

Merci quand même de votre aide.

Altonfrere
Altonfrere
Niveau 10
25 octobre 2005 à 00:11:11

disons que les tableaux de fonctions tels que tu le souhaiterai n´est pas vraiment possible ...

pour les types classiques ou même des objets il est facile au compilo d´interpréter la taille des données à référencer. Lorsque l´on écrit char bidule[], ou int *valeur, MaClasse MonObjet, etc... on connait la taille du char, int, etc.. on connait donc l´emplacement des prochains éléments en mémoire.

Une fonction étant déjà un pointeur vers le début du code de celle-ci, il est par contre difficile d´en connaître sa taille et encore moins évident de se dire que les fonctions du même genre sont les unes à la suite des autres en mémoire ... donc vouloir manipuler les fonctions comme des tableaux potentiels n´a pas vraiment de sens.

La seule issue est donc les tableaux de pointeurs de fonction. Là on sait que le tableau contient des pointeurs (taille fixe).

Altonfrere
Altonfrere
Niveau 10
25 octobre 2005 à 00:12:45

et MrGoTo :) non non pas mort, la branche résiste encore :) tel le roseau qui plie sous le vent mais qui pête pas lol

kufa
kufa
Niveau 9
26 octobre 2005 à 06:34:43

Toujours est-il que ça ne permet pas d´écrire ça :
tracer((math_call*)&my_square, 0, 3.14, 1 );

Evidement: my_square et &my_square sont equivalent. Pourquoi? Car my_square est un pointeur sur une fonction (un nombre si on veut simplifier). On ne peut pas ecrire par ex int *a = &5; donc par defaut les compilo considere que &fonction correspond a fonction.
Comment remedier a ca? Tout simplement comme pour un int, en stockant le nombre qq part:
int a_valeur = 5;
int *a = &a_valeur;
cf mon exemple que j´ai paste plus bas.

disons que les tableaux de fonctions tels que tu le
souhaiterai n´est pas vraiment possible ...

Si, c´est totalement possible.
Ton explication est fausse, une fonction etant toujours representee par un pointeur.
Dans mon exemple je montre que l´on peut caster une fonction en un void* et de nouveau en une fonction. Je montre egalement que l´on peut parcourir un tableau de fonctions.

Le code: (http://rafb.net/paste/results/GWdYEN27.html)

  1. include <stdio.h>
  2. include <math.h>

typedef double (*math_call)(double);

void tracer( math_call f, double xmin, double xmax, double increment )
{
double x;
for( x = xmin; x <= xmax; x += increment )
{
double valeur = f( x );
printf( "%lf : %lf\n", x, valeur );
}
}

void tracer_all( math_call *functions, double xmin, double xmax, double increment )
{
while( *functions )
{
tracer( *functions++, xmin, xmax, increment );
}
}

void tracer_premier( math_call *functions, double xmin, double xmax, double increment )
{
tracer( *functions, xmin, xmax, increment );
}

double my_square( double nombre )
{
return nombre * nombre;
}

double my_test( double nombre, int a )
{
return my_square( nombre );
}

int main()
{
math_call myCos = cos;
math_call mySin = sin;
math_call mySquare = my_square;

math_call funcs_1[] = { myCos, mySin, 0L };

void *tmp = (void*) cos;
math_call myCos2 = (math_call) tmp;

tracer( mySquare, 0, 5, 1 );
tracer( myCos, 0, 3.14, 1 );

tracer_all( funcs_1, 0, 3.14, 1 );
tracer_premier( funcs_1, 0, 3.14, 1 );
tracer_premier( &myCos, 0, 3.14, 1 );

tracer( my_test, 0, 3.14, 1 ); // warning, normal, mais ca marche toujours
tracer( myCos2, 0, 3.14, 1 ); // ca marche

return 0;
}

Altonfrere
Altonfrere
Niveau 10
26 octobre 2005 à 07:39:56

Le problème reste toujours posé ...

le but était (me semble-t-il) d´appeler la fonction tracer aussi bien avec une seule fonction qu´avec une série de fonctions

kufa
kufa
Niveau 9
26 octobre 2005 à 19:45:02

C´est ce que je fais la:
tracer_premier( funcs_1, 0, 3.14, 1 );
tracer_premier( &myCos, 0, 3.14, 1 );

/kUfa

dnob700
dnob700
Niveau 10
27 octobre 2005 à 16:52:02

oui, effectivement, merci.

Bon, dans le même temps, j´ai ré-écrit ça en version orienté objet donc leproblème ne se pose plus car je rajoutte ou je retire des fonctions à tracer par l´objet qui les traces et non plus la fonctions.

Ca rend l´appel de la fonction beaucoup beaucoup plus clair (avant j´avais 14 paramètres à passer à la fonction Tracer).

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Programmation
  • Création de sites web
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment