IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Tableau de pointeurs sur fonctions.


Sujet :

C

  1. #1
    Membre régulier Avatar de JulieCarree
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 50
    Points : 94
    Points
    94
    Par défaut Tableau de pointeurs sur fonctions.
    bonjour,
    pour declarer un tableau de six pointeurs void sur fonctions sans retour ni arguments et sans typedef, apres moultes recherches, j'ai pondu ça, ça à l'air de fonctionner .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void (*parole[6])(void);
    d'apres les " Notes sur le langage C par Emmanuel Delahaye " trouvé sur dvp
    XXI-B-2-a. Remarques importantes▲
    void* n'est pas un type correct pour un pointeur de fonction ;
    Il n'existe pas de type générique pour les pointeurs de fonctions.


    ma question :
    faut-il utiliser des fonctions qui retournent un resultat ?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 702
    Points
    23 702
    Par défaut
    Hello,

    Je crois que ce qu'il voulait dire, c'est qu'on ne met pas un pointeur de fonction dans un objet de type « void * » tout court pour que ce soit plus simple. Mais tu as bien sûr tout-à-fait le droit de déclarer des pointeurs sur des fonctions de type void.

    L'idée générale est qu'un pointeur « void * » pointe quelque chose dont le type est indéfini, ce qui peut donc être n'importe quoi. Néanmoins, ce « n'importe quoi » ne peut pas être une fonction. C'est principalement dû au fait que les architectures Harvard stockent code et données dans des espaces d'adressage différents et que l'on considère que ce qui est pointé par « void * » est une donnée.

    On en parlait ici.

  3. #3
    Membre régulier Avatar de JulieCarree
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 50
    Points : 94
    Points
    94
    Par défaut
    merci de ta reponse,
    j'ai survolé le topic que tu as mis en lien, donc ce n'est pas defini dans la norme C, de plus suivant l'architecture ( bus de données et instructions ) il y a une impossibilité materielle .
    sur gcc c'est permis et c'est defini dans la norme posix .

    j'ai ecris ce petit essait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    void bonjour ( void );
    void adieu ( void );
    void merci ( void );
    void siouplait ( void );
    void atchoum ( void );
    void casse_toi ( void );
     
    int main ( void )
    {
            int gogo;
            void (*parole[6])(void); /* tableau de six pointeurs void sur fonctions sans retour ni arguments */
     
            parole[0] = bonjour;
            parole[1] = adieu;
            parole[2] = merci;
            parole[3] = siouplait;
            parole[4] = atchoum;
            parole[5] = casse_toi;
     
            for ( gogo = 0; gogo < 6; ++gogo)
                    parole[gogo]();
     
            gogo = 5;
            do
            {
                    parole[gogo]();
                    --gogo;
             }
             while  (gogo >= 0);
     
            return 0;
    }
    Compilé avec gcc -pedantic -ansi -W -Wall argue_1.c -o argue_1, pas de plaintes de gcc .

  4. #4
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Uuuuh... chez moi ça ne link pas...

    Undefined reference to 'bonjour'
    Et sur chaque nom de fonction...

    D'un seul coup ça m'intéresse, car je m'étais assez énervé un soir avec les pointeurs sur fonction !

    EDIT : hahahaha... bah oui.. je suis c*n... il trouve pas les réf c'est normal...
    Avec un -c ça marcherait "mieux"

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    Citation Envoyé par JulieCarree Voir le message
    bonjour,
    pour declarer un tableau de six pointeurs void sur fonctions sans retour ni arguments et sans typedef, apres moultes recherches, j'ai pondu ça, ça à l'air de fonctionner .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void (*parole[6])(void);
    moi, pour un tableau de fonction void f(void), je ferai oplutot ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    typedef void (*action_t)(void);
    void bonjour ( void );
    void adieu ( void );
    void merci ( void );
     
    int main ( void ) {
        action_t parole[]={bonjour, adieu, merci};
        return 0;
    }

  6. #6
    Membre régulier Avatar de JulieCarree
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 50
    Points : 94
    Points
    94
    Par défaut
    @ Metalman
    Uuuuh... chez moi ça ne link pas...

    Citation:
    Undefined reference to 'bonjour'
    normal, les fonctions sont en option

    @ leternel,
    merci, j'avais dejà trouvé sur le net avec le typedef, mais sans le typedef, pas evident de trouver comment definir un tableau de pointeurs void sur fonctions .

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    C'est l'intérêt même du typedef, justement: améliorer la lisibilité, et l'écrivabilité.
    En plus d'ajouter une information sémantique si les noms sont bien choisit.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Oui, pour les pointeurs de fonction, je dirais que les typedefs sont pratiquement indispensable à une bonne compréhension.
    Il n'y a qu'à voir le prototype de la fonction signal() pour voir à quel vitesse la manipulation de pointeurs de fonction devient compliquée sans typedefs.

  9. #9
    Membre régulier Avatar de JulieCarree
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 50
    Points : 94
    Points
    94
    Par défaut
    @ medinoc

    ok je sais, et je l'ai bien compris, mais ma demarche est de comprendre comment ça marche sans typedef, j'apprends tout seul pour le plaisir de comprendre, je ne dois pas rendre de projet demain à la premiere heure, mais merci à tous de prendre le temps de me repondre, moi qui ne suis pas pro de l'informatique .

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 702
    Points
    23 702
    Par défaut
    Citation Envoyé par JulieCarree Voir le message
    mais merci à tous de prendre le temps de me repondre, moi qui ne suis pas pro de l'informatique .
    Tu en fais déjà plus que pas mal d'étudiants qui se destinent pourtant à cette voie. :-)
    Bonne chance pour la suite.

  11. #11
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Je me permets d'insister et d'abonder dans le sens de Médinoc.

    Dès que l'on parle de pointeur de fonction, il faut aller le plus vite possible vers un typedef sinon, c'est vite illisible.

    Qu'est ce que tu préfères ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void (*parole[6])(void);
    qui est assez illisible ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef void (*action_t)(void);
    action_t parole[6];
    La 2eme écriture à le mérite de concentrer la difficulté de lecture dans la 1ere ligne. Une fois qu'on l'a comprise (ou admise), la 2eme ligne est facile à appréhender, c'est un tableau de 6 action_t.

    imagine une fonction à laquelle tu passe un pointeur de fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void execute(action_t action)
    {
       action();
    }
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void execute(void (* action)(void))
    {
       action();
    }
    D'après toi, quelle est la forme la plus lisible et compréhensible (et encore, je ne suis pas sûr que la 2eme forme soit valide syntaxiquement alors que la 1ere l'est)

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 702
    Points
    23 702
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Oui, pour les pointeurs de fonction, je dirais que les typedefs sont pratiquement indispensable à une bonne compréhension.
    Il n'y a qu'à voir le prototype de la fonction signal() pour voir à quel vitesse la manipulation de pointeurs de fonction devient compliquée sans typedefs.
    Citation Envoyé par JulieCarree Voir le message
    ok je sais, et je l'ai bien compris, mais ma demarche est de comprendre comment ça marche sans typedef, j'apprends tout seul pour le plaisir de comprendre, je ne dois pas rendre de projet demain à la premiere heure, mais merci à tous de prendre le temps de me repondre, moi qui ne suis pas pro de l'informatique .
    Citation Envoyé par ram-0000 Voir le message
    Je me permets d'insister et d'abonder dans le sens de Médinoc.

    Dès que l'on parle de pointeur de fonction, il faut aller le plus vite possible vers un typedef sinon, c'est vite illisible.
    Moi, je dois dire que je me rangerais aujourd'hui plutôt du côté de JulieCarree. Certes, les déclarations de pointeurs de fonctions font parties des choses les moins lisibles en C et je recommande toujours chaudement aux débutants de les décomposer en typedefs. C'est particulièrement vrai lorsqu'on doit déclarer le même type de pointeur à de nombreuses reprises tout au long du code et lorsque l'on a plusieurs prototypes de fonctions similaires mais différents, auquel cas il faut être très attentif.

    Cela dit, ça a fini par me lasser un peu et une fois que l'on a bien compris comment ça fonctionne, un pointeur de fonction devient aussi facile à lire que n'importe quelle autre déclaration et du coup, ça me fait suer d'avoir à remonter à chaque fois pour trouver le typedef associé. En outre, il faut veiller à bien choisir son nom de type car autrement, on ne peut plus savoir au premier coup d'œil s'il s'agit ou nom d'un pointeur sur un objet ou sur du code.

    C'est pour cela que, dans le cas présent, je préfère l'approche de la primo-postante : un typedef pour faire une seule déclaration, c'est un peu excessif. En plus, elle manipule avec brio la déclaration d'un tableau de pointeurs de fonctions en une seule expression, et c'est un exercice auquel tout le monde devrait se livrer au moins une fois.

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    Et comment écrirais-tu sans typedef la déclaration suivante?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef int (*min_t)(int, int);
    min_t selectFunction(int indice, min_t array[], int size);
    Même moi, après dix ans de C, je ne sais pas le faire sans passer par l'essai-erreur de compilation.

  14. #14
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Uuuuuh... oui mais là... renvoyer min_t ça revient à faire de l'ordre supérieur il me semble...
    Pas sûr que le C soit vraiment fait pour...

  15. #15
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    c'est juste un peu de masquage au dessus d'un tableau de min_t, qui permet un controle d'erreur.

    Une meilleure forme serait d'avoir une structure contenant le tableau, sa taille max et actuelle, et quelques fonctions d'acces (add, remove, get)

  16. #16
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 702
    Points
    23 702
    Par défaut
    Citation Envoyé par leternel Voir le message
    Et comment écrirais-tu sans typedef la déclaration suivante?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef int (*min_t)(int, int);
    min_t selectFunction(int indice, min_t array[], int size);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int (* selectFunction (int indice,int(* array[])(int,int),int size))(int,int);
    Écrit sur le forum et vérifié avec succès a posteriori.

    Même moi, après dix ans de C, je ne sais pas le faire sans passer par l'essai-erreur de compilation.
    J'aime beaucoup le « même moi » ! :-)

    J'ai eu de la chance avec le prototype ci-dessus mais il m'arrive aussi de faire des tests empiriques. C'est normal et ça ne concerne pas que les pointeurs de fonctions. Il n'est pas interdit d'utiliser des typedefs et heureusement, surtout quand ils introduisent de la sémantique. C'est aussi un service rendu aux autres lecteurs, surtout quand ils sont débutants.

    Par contre, ça ne doit pas être obligatoire non plus et, à dire vrai, c'est précisément parce que peu de gens savent réellement comment est construit un pointeur de fonction et pourquoi il l'est de cette façon que la plupart d'entre eux trouvent cela difficile. En plus, ce prototype est suffisamment long pour le justifier, mais faire un typedef exprès pour redéfinir « void (*)(void); », par exemple, ça me fait suer.

    C'est pour cela qu'il faut pratiquer un tout petit peu, par exemple une heure seulement en début d'apprentissage, pour ne plus avoir à y revenir après. C'est ce que fait Julie spontanément en cherchant à aller au fond des choses et c'est saluable.

  17. #17
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    En effet, comprendre est une très bonne idée.
    La règle de lecture de type est assez simple, c'est l'écriture qui peut vite devenir complexe

  18. #18
    Membre régulier Avatar de JulieCarree
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 50
    Points : 94
    Points
    94
    Par défaut
    Citation Envoyé par leternel Voir le message
    En effet, comprendre est une très bonne idée.
    La règle de lecture de type est assez simple, c'est l'écriture qui peut vite devenir complexe
    une tres juste conclusion pour ce fil, et encore merci de vos lumieres .

  19. #19
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Citation Envoyé par JulieCarree Voir le message
    @ leternel,
    merci, j'avais dejà trouvé sur le net avec le typedef, mais sans le typedef, pas evident de trouver comment definir un tableau de pointeurs void sur fonctions .
    Salut, tu devrais essayer cdecl (version web):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    cdecl> declare parole as array 6 of pointer to function (void) returning void
    void (*parole[6])(void )
    cdecl> 
    cdecl> declare selectFunction as function (int, array of pointer to function(int, int) returning int, int) returning pointer to function (int, int) returning int
    int (*selectFunction(int , int (*[])(int , int ), int ))(int , int )
    Amuses-toi bien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 09/01/2013, 15h30
  2. Réponses: 1
    Dernier message: 22/12/2009, 11h40
  3. [BCB6]Tableau de pointeurs sur fonctions
    Par rtg57 dans le forum C++Builder
    Réponses: 6
    Dernier message: 06/10/2006, 20h49
  4. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo