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 :

Nom de fonction avec une partie variable


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Nom de fonction avec une partie variable
    Bonjour,
    Pour économiser de la mémoire programme sur mon microcontrôleur je voudrais appeler une fonction parmi plusieurs qui sont identiques (pas d'argument)

    pour faire simple, au lieu d'appeler:

    mafonction3();

    je voudrais faire

    mafonctionx() ou x prendrait la valeur 3

    Merci

  2. #2
    Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Octobre 2019
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2019
    Messages : 21
    Points : 44
    Points
    44
    Par défaut
    Je ne sais pas si j'ai bien compris, mais le préprocesseur pourrait t'aider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define mafonction(x) mafonction ## x()
    Appelle ainsi :


  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Corluk

    Merci pour ta réponse
    Ce que tu me proposes va remplacer lors de la compilation alors que je souhaite plutôt une partie variable que va appeler la bonne fonction
    c'est a dire que le x entre crochet serait une partie variable

    mafonction[x](); avec [x] pouvant prendre une valeur comprise entre 1 et 20 par exemple

    si avant de demander l’exécution de la ligne ci-dessus et que x vaut 6 j'aurais

    je vais executer
    mafonction6();

    puis quelques cycles plus tard avant de demander l’exécution de la ligne et que x vaut 2

    je vais appeler
    mafonction2();

    Voilà j'espère avoir été plus clair

  4. #4
    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 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Une fois compilée les fonctions n'ont plus de nom mais juste une adresse.
    Ta raison d'économiser de la mémoire est au moins fausse parce que tu n'économiseras rien.
    Au lieu d'écrire call3(); call2(); tu veux avoir une variable x qui prenne les valeurs 2,3, ... et devine quelle fonction appeler.
    Donc pour économiser de la mémoire tu ajoutes une variable ?
    Le moyen le plus simple d'appeler une fonction c'est de l'appeler directement. Si tu rajoutes une indirection, tu vas toujours perdre du temps à résoudre l'indirection avant de faire l'appel réel.
    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.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par LE_BU Voir le message
    Voilà j'espère avoir été plus clair
    Non pas du tout quel est le but de la manœuvre ?

    Si tu prends la solution @Corluk, ou tu passes le nombre en paramètre de ta fonction, tu vas avoir 1 gros switch.
    Mais si chaque embranchement a beaucoup de code (> plus de 20 lignes) ou il y a beaucoup d'embranchements (apparemment 20), la taille de ta fonction va exploser.
    Ou alors, tu fais 1 embranchement == 1 appel d'une fonction.

    Mais quelle que soit la façon de coder, tu vas avoir 1 grosse fonction ou alors 20+1 petites fonctions.
    Que veux-tu faire au juste ? Est-ce que tu veux que tes fonctions ne soient pas toutes présentes en mémoire - c'est à dire par exemple, charger la fonction/ l'embranchement 5 et 7, mais pas les autres ?
    Ce n'est pas très clair ?

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 642
    Points
    7 642
    Par défaut
    Bonjour,

    Générer un nom de fonction ça n'a de sens qu'au moment de la compilation, car à l'exécution les noms n'existent plus (heureusement et c'est pour ça qu'on n'utilise pas de langage de script sur microcontrôleur). Donc seul le préprocesseur peut faire cela comme la solution de Corluk.
    Ce que tu peux faire c'est utiliser un tableau de pointeurs de fonctions. Et les noms n'y joueront aucun rôle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void fonction1(void);
    void deuxiemeFonction(void);
    void fonction3(void);
     
    static const void (*MesFonctions[3])(void) = { // tableau de pointeurs sur void fct(void)
        fonction1,
        deuxiemeFonction,
        fonction3
    };
     
    void appelerFonction( int x) {
        (*MesFonctions[x])();  // appeler la x-ième fonction
    }

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Une fois compilée les fonctions n'ont plus de nom mais juste une adresse.
    Ta raison d'économiser de la mémoire est au moins fausse parce que tu n'économiseras rien.
    Au lieu d'écrire call3(); call2(); tu veux avoir une variable x qui prenne les valeurs 2,3, ... et devine quelle fonction appeler.
    Donc pour économiser de la mémoire tu ajoutes une variable ?
    Le moyen le plus simple d'appeler une fonction c'est de l'appeler directement. Si tu rajoutes une indirection, tu vas toujours perdre du temps à résoudre l'indirection avant de faire l'appel réel.
    Je suis d'accord que les fonctions ont une adresse une fois compilé mais je pense que de faire une programme :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (appellefonction==2) mafonction2();
    if (appellefonction==3) mafonction3();
        |
        |
    if (appellefonction==N-1) mafonctionN-1();
    if (appellefonction==N) mafonctionN();

    sera beaucoup plus gourmand en mémoire que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mafonction[appellefonction]();

    Surtout si N est grand

  8. #8
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Avril 2020
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2020
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Bonjour,

    Générer un nom de fonction ça n'a de sens qu'au moment de la compilation, car à l'exécution les noms n'existent plus (heureusement et c'est pour ça qu'on n'utilise pas de langage de script sur microcontrôleur). Donc seul le préprocesseur peut faire cela comme la solution de Corluk.
    Ce que tu peux faire c'est utiliser un tableau de pointeurs de fonctions. Et les noms n'y joueront aucun rôle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void fonction1(void);
    void deuxiemeFonction(void);
    void fonction3(void);
     
    static const void (*MesFonctions[3])(void) = { // tableau de pointeurs sur void fct(void)
        fonction1,
        deuxiemeFonction,
        fonction3
    };
     
    void appelerFonction( int x) {
        (*MesFonctions[x])();  // appeler la x-ième fonction
    }
    Bonjour, ta solution me semble la plus approprié ... mais je pensais qu'il existait quelque chose de plus simple que j'ignorais

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par LE_BU Voir le message
    Je suis d'accord que les fonctions ont une adresse une fois compilé mais je pense que de faire une programme [...] sera beaucoup plus gourmand en mémoire que [...] Surtout si N est grand
    Ben non parce que le switch utilise des tables de branchements ("jump tables" en anglais ) et donc c'est gros modo équivalent à un tableau de pointeurs.

    Après , il faudra sûrement mettre l'optimisation à fond lors de la compilation.

  10. #10
    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 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Plus N est grand, plus tu gaspilles de mémoire.
    Prenons N = 1000. Maintenant en plus de 1000 fonctions, tu te retrouves avec un tableau de 1000 pointeurs, donc 2-8ko de mémoire utilisées pour écrire call(3); au lieu de call3(); quand tu veux appeler la troisième fonction.
    Je vois pas où tu vois un gain là-dedans
    Les tableaux de fonction ont une utilité, mais optimiser la mémoire en fait pas partie.
    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.

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 1
    Points : 3
    Points
    3
    Par défaut Bonjour
    Je ne comprends pas bien le tableau de pointeur sur fonction

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par L'EMPEREUR LION Voir le message
    Je ne comprends pas bien le tableau de pointeur sur fonction
    Une fonction c'est un code exécutable identifié par un nom. Mais au niveau machine, ce nom c'est simplement une adresse.
    Donc (exemple) si tu écris void toto(int n) {printf("toto %d\n", n)}, tu crées une fonction dont le nom "toto" correspond à l'adresse d'un code. Tu as alors le droit de créer un pointeur qui récupère cette adresse.
    Ce code étant void et recevant un int, ce pointeur sera alors défini ainsi: void (*pt)(int) signifiant "pt va contenir une adresse" et "*pt" correspond à un code de fonction de type void et recevant un int. Ensuite, tu lui affectes l'adresse de la fonction toto de façon naturelle comme pour toute autre valeur pt=toto (mais pas de parenthèse à "toto" car tu ne veux pas l'exécuter, juste la nommer).
    De là, tu peux exécuter le code de toto soit de la façon classique toto(123) soit par le pointeur qui contient lui-aussi l'adresse de ce code => (*pt)(456) mais les parenthèses sont obligatoires à cause des priorités.

    Une fois que tu comprends ce concept qu'une fonction n'est avant tout qu'une adresse que tu peux stocker dans un pointeur, c'est pas compliqué à étendre à un tableau de pointeurs pouvant stocker diverses adresses de diverses fonctions.
    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]

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

Discussions similaires

  1. Renommer nom de fichier avec une partie d'un texte
    Par bebebatch dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 01/02/2019, 21h38
  2. [XL-2010] Ouvrir un fichier avec une partie du nom variable
    Par PIERRE-DEVIN dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 05/09/2018, 14h25
  3. Réponses: 12
    Dernier message: 10/05/2017, 16h35
  4. [XL-2007] Chercher dossier avec une partie variable connue
    Par blacktiger_83 dans le forum Excel
    Réponses: 8
    Dernier message: 03/05/2016, 11h13
  5. Réponses: 3
    Dernier message: 09/03/2016, 16h23

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