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 constantes contenant des adresses de fonction


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développement hardware et software
    Inscrit en
    Septembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développement hardware et software
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2018
    Messages : 4
    Points : 8
    Points
    8
    Par défaut tableau de constantes contenant des adresses de fonction
    Bonjour à tous,

    dans un programme en C (compilateur XC16 de Microchip), je cherche à déclarer un tableau de constantes contenant une liste d'adresses de fonctions.
    La déclaration devrait avoir la forme:
    const ???montableau[] = {&(fonction_1), ..., &(fonction_n)};

    Je n'arrive pas à trouver d'aide dans les bouquins ni sur le web. Pouvez-vous m'aider ?

    Merci de m'avoir lu. A bientôt.

    Claude

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur
    Inscrit en
    Juillet 2009
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 416
    Points : 1 443
    Points
    1 443
    Par défaut
    Salut,

    Tu aurais trouvé si tu avais cherché avec le terme "pointeur de fonction" plutôt qu'"adresse de fonction":
    https://chgi.developpez.com/pointeur/

    Le paragraphe VII contient la réponse à ta question, à savoir par quoi il faut remplacer le "???".
    Mais pas besoin des "&" dans ton tableau.

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Un petit typedef bien senti pourrait simplifier l'écriture

    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
    #include <stdio.h>
     
    typedef void(*callback)(void);
     
    void f()
    {
        puts("f");
    }
     
    void g()
    {
        puts("g");   
    }
     
    callback array[] = {f, g};
     
    int main()
    {
        array[0]();
        array[1]();
    }

  4. #4
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 439
    Points
    2 439
    Par défaut
    Salut, bienvenue sur le forum.

    En complément des réponses fournies, tes fonctions doivent impérativement avoir la même signature (même types d'arguments et même type de retour), car un pointeur de fonction est défini pour une signature précise.

    Autrement dit, un pointeur void(*callback)(void); ne peut désigner qu'une fonction de genre void foo();.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Plus exactement, il est possible de réaliser un appel via un pointeur de fonction si et seulement si celui-ci contient l'adresse d'une fonction portant la même signature.

    On peut très bien faire transiter l'adresse d'une fonction dans un pointeur de fonction (pas de donnée !) d'un type incompatible, à la condition expresse de ne pas réaliser d'appel.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Développement hardware et software
    Inscrit en
    Septembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développement hardware et software
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2018
    Messages : 4
    Points : 8
    Points
    8
    Par défaut
    Bonjour à tous,

    merci pour l'intérêt que vous avez porté à ma question et pour vos réponses. Mais, je n'ai pas dû insister suffisamment sur le fait que je cherche à déclarer un tableau de constantes. Vous m'indiquez dans vos réponses comment déclarer un tableau de variables. J'écris un programme pour microcontrôleur. Les tailles de mémoires FLASH et RAM sont donc très limitées, il ne faut pas en gaspiller.
    Le fait de déclarer un tableau de variables occupe de la place en RAM, alors que je n'écris jamais dans ce tableau, je ne fais que le lire. D'où ma demande de constantes.
    Ma question est donc toujours d'actualité, "comment déclarer un tableau de constantes pointeurs de fonctions ?
    Merci de m'avoir lu. A bientôt.

    Claude

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    constexpr callback array[] = {f, g};
    ?

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Développement hardware et software
    Inscrit en
    Septembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développement hardware et software
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2018
    Messages : 4
    Points : 8
    Points
    8
    Par défaut
    ça marche impeccable. Merci pour votre aide.
    Bonne journée, à bientôt.
    Claude

  9. #9
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Ou pas, puisque nous sommes sur le forum C.

    Si ton tableau est adressé de manière statique, la décision de son élision reste à la discrétion du compilateur. S'il est adressé de manière dynamique, je ne vois pas d'autre solution que de le charger en mémoire..

    Peut-être peux-tu nous donner plus de détails sur la manière dont tu comptes l'utiliser.

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut


    Pardon.... 'const' au lieu de 'constexpr' est la seule alternative standard. Après, il reste toujours des #pragma éventuels pour forcer la mise en flash.

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Avez-vous remarqué qu'avec les pointeurs de fonction, l'opérateur "etoile" était ignoré ? C'est un truc qui m'a toujours fasciné.

    Reprenons l'exemple de Bktero mais sans le typedef qui masque pudiquement la dure réalité des pointeurs...
    Code c : 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
    #include <stdio.h>
     
    void f()
    {
    	puts("f");
    }
     
    void g()
    {
    	puts("g");   
    }
     
    void (*array[])(void)={f, g};
     
    int main()
    {
    	(*array[0])();
    	(****array[1])();
    }
    Ca fonctionne pareil. Et vous pouvez mettre à la place 150 étoiles si ça vous chante. C'est presque comme si le "pointé de" était identique à son pointeur...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Développement hardware et software
    Inscrit en
    Septembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développement hardware et software
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2018
    Messages : 4
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Ou pas, puisque nous sommes sur le forum C.

    Si ton tableau est adressé de manière statique, la décision de son élision reste à la discrétion du compilateur. S'il est adressé de manière dynamique, je ne vois pas d'autre solution que de le charger en mémoire..

    Peut-être peux-tu nous donner plus de détails sur la manière dont tu comptes l'utiliser.
    Bonjour Matt_Houston,

    ma question était "comment déclarer un tableau de constantes ..." La réponse de Bktero fait tout à fait ce travail.
    Si vous vous demandez ce que je fais avec, éh bien mon programme exécute la fonction correspondant à une touche du clavier. Le code, en partant de l'exemple de Bktero serait le suivant:

    char index;
    void (*monpointeur)(void);
    ------------------------------
    ------------------------------
    ------------------------------
    index = lectureClavier();
    monpointeur = array[index];
    monpointeur ();
    ------------------------------
    ------------------------------
    ------------------------------

    et voilà, la fonction correspondant à la touche du clavier est exécutée.
    Bonne journée à, tous.

    Claude

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par claude72 Voir le message
    Le code, en partant de l'exemple de Bktero serait le suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char index;
    void (*monpointeur)(void);
    ------------------------------
    ------------------------------
    ------------------------------
    index = lectureClavier();
    monpointeur = array[index];
    monpointeur ();
    ------------------------------
    ------------------------------
    ------------------------------
    et voilà, la fonction correspondant à la touche du clavier est exécutée.
    Mouais. Ce "monpointeur" ne sert pas à grand chose surtout pour quelqu'un qui se dit aussi préoccupé par l'espace mémoire utilisé => array[index]() le fait aussi voire même array[lectureClavier()]() si on ne craint pas de surcharger un peu les instructions.

    Et
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par claude72 Voir le message
    ma question était "comment déclarer un tableau de constantes ..." La réponse de Bktero fait tout à fait ce travail.
    constexpr n'existe pas en C. Si ça passe, c'est que tu génères ton code machine avec un compilateur C++.


    Citation Envoyé par claude72 Voir le message
    Si vous vous demandez ce que je fais avec, éh bien mon programme exécute la fonction correspondant à une touche du clavier.
    On ne peut donc faire l'économie d'une table d'association rang -> pointeur. Que le tableau soit déclaré constexpr n'y change rien, il sera présent quelque part en mémoire.

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par claude72 Voir le message
    Vous m'indiquez dans vos réponses comment déclarer un tableau de variables.
    T'es conscient qu'une constante est une variable et prend autant de mémoire ?
    Sauf à avoir des constantes très simples que le compilo saura optimiser et enlever pendant la compilation, chose qu'un tableau de pointeur ne sera sûrement pas.
    Donc le seul moyen pour ne pas gaspiller de mémoire est de ne pas utiliser de variables, constantes ou pas.
    Et dans ce cas ce serait une fonction avec un gros switch pour rediriger vers la bonne fonction. Ça évitera aussi les crashs quand tu utilises une touche non prévue ou initialises mal le tableau.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  16. #16
    Membre averti
    Homme Profil pro
    très occupé
    Inscrit en
    Juillet 2014
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : très occupé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 137
    Points : 411
    Points
    411
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    constexpr n'existe pas en C. Si ça passe, c'est que tu génères ton code machine avec un compilateur C++.
    Oui, en C cela serait const comme déjà été dit plus haut.

    Citation Envoyé par Matt_Houston Voir le message
    On ne peut donc faire l'économie d'une table d'association rang -> pointeur. Que le tableau soit déclaré constexpr n'y change rien, il sera présent quelque part en mémoire.
    Oui, cela occupe "de la mémoire", mais toute la question est de savoir laquelle.

    Comme le posteur originel travaille sur un microcontrolleur avec le compilateur XC16 de Microchip, la mémoire peut être une ROM (la mémoire flash dans laquelle les constantes sont rangées par sa chaîne de compilation), ou la RAM (permettant une lecture / écriture par le programme et généralement disponible en quantité plus limitée).

    Dans le cas de cette chaîne de compilation : http://ww1.microchip.com/downloads/e...071GFinal1.pdf

    3.4.4.7
    HOW CAN I LOAD A VALUE INTO FLASH MEMORY?
    The compiler provides different ways of defining Flash variables.
    • A variable can be explicitly placed into Flash using an appropriate space attribute.
    • Variables are implicitly placed into Flash in the default const-in-code memory model if they have the C const type qualifier

  17. #17
    Membre expérimenté
    Homme Profil pro
    Développeur
    Inscrit en
    Juillet 2009
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Juillet 2009
    Messages : 416
    Points : 1 443
    Points
    1 443
    Par défaut
    Bonjour,

    C'est un peu tard pour le mentionner, mais la rubrique Embarqué était peut-être plus appropriée pour cette question, les gens qui le fréquentent auraient sûrement donné des réponses plus pertinentes que les nôtres (ici, on s'attend à avoir des questions sur du C "standard"). Rien que le fait de poster là-bas aurait permis de mieux cerner le sens de la question ^^'

  18. #18
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Je suis curieux de savoir en quoi la pertinence des réponses apportées serait absente, ou partielle.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/09/2014, 22h42
  2. Réponses: 5
    Dernier message: 15/03/2012, 00h26
  3. Réponses: 1
    Dernier message: 03/07/2011, 16h59
  4. [FPDF] Tableau à une dimension contenant des valeurs
    Par kluck3000 dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 23/05/2008, 13h34
  5. Réponses: 2
    Dernier message: 08/03/2007, 01h49

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