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 :

pointeur tableau et fonction


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 209
    Par défaut pointeur tableau et fonction
    salut :
    je me demande comment passer un tableau comme argument d'une fonction à condition que la fst modifie réellement les valeurs du tableau (passage par adresse) et merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    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 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yassinegoth Voir le message
    salut :
    je me demande comment passer un tableau comme argument d'une fonction à condition que la fst modifie réellement les valeurs du tableau (passage par adresse) et merci
    Le nom d'un tableau est déjà une adresse. Tu passes donc simplement le nom du tableau à ta fonction. Et au risque de paraître un peu cinglant, tu pourrais lire les bases du C avant de venir ici...
    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]

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 209
    Par défaut
    resalut :
    tu as toute à fait raison d'utiliser la phrase "" Et au risque de paraître un peu cinglant, tu pourrais lire les bases du C avant de venir ici...""
    car ce que je cherche réellement à savoir c'est le suivant :

    si on utilise des pointeurs pour mémoriser voir manipuler des variables par leurs adresses je me demande donc qu'il est l'interet des pointeurs sur des fcts

    et merci

  4. #4
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Pour te donner un exemple de l'utilité des pointeurs de fonctions, regarde la fonction qsort() et comprend par toi même.
    Cordialement.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    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 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yassinegoth Voir le message
    resalut :
    tu as toute à fait raison d'utiliser la phrase "" Et au risque de paraître un peu cinglant, tu pourrais lire les bases du C avant de venir ici...""
    car ce que je cherche réellement à savoir c'est le suivant :

    si on utilise des pointeurs pour mémoriser voir manipuler des variables par leurs adresses je me demande donc qu'il est l'interet des pointeurs sur des fcts
    Bah... tu aurais pu le demander de suite.
    Nicolas Sitbon t'as parlé de qsort() qui est une fonction de tri universel et qui a donc besoin, pour trier des éléments qu'elle ne connait pas à l'avance, de recevoir un pointeur sur la fonction qui sert à comparer 2 éléments => ainsi elle peut se servir du pointeur pour appeler la fonction chaque fois qu'elle a besoin de comparer 2 éléments.
    Donc, pour simplifier, on utilise un pointeur de fonction chaque fois qu'on ne sait pas à l'avance quelle fonction on utilisera dans un cas particulier.

    Par exemple, une fois, j'ai dû faire une appli où l'utilisateur pouvait choisir à l'avance les impressions qu'il voulait lancer. Il commençait par choisir ses impression puis une fois sélectionnées, il les lançait toutes d'un coup.
    J'avais donc une fonction dédiée à chaque impression. A chaque impression choisie, je stockais le pointeur associé à la fonction dans un tableau de pointeurs de fonctions.
    Une fois l'ensemble validé, je n'avais plus qu'à traiter mon tableau en appelant les pointeurs de fonctions les uns après les autres => les fonctions associées étaient appelées automatiquement.
    C'est un exemple comme un autre...
    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]

  6. #6
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    La dernière fois que j'ai utilisé des pointeurs sur fonctions, c'était pour gérer le traitement des trames reçues et envoyées dans une application client/serveur. Voici un bout de code utilisé pour créer les trames qui peut t'aider à comprendre.

    1º/ Une structure pour identifier quelle fonction doit être appelée au regard de l'ID de la trame à créer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct _FORMATTER {
       char idframe;
       void (*function)(void *dest_struct, va_list args);
    } FORMATTER;
    2º/ Un tableau contenant les différents ID et fonctions correspondantes (3 trames dans ce cas pour simplifier)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    const FORMATTER formatters[] = 
    {
       { ID_CONNECTION,           fb_connection  },
       { ID_DOWNLOAD,             fb_downres     },
       { ID_CHKSUM,               fb_chksum      }
    };
    3º/ Une fonction qui permet de recupérer un pointeur sur fonction au regard de l'ID de la trame
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void *get_formatter(const char idframe)
    {
       int i;
     
       for(i = 0; i < 3; i++)
          if(formatters[i].idframe == idframe)
             return formatters[i].function;
     
       return NULL;
    }
    Et maintenant, l'appel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       void   (*function)(void *, va_list);
       function = get_formatter(idframe);
       function(dest_struct, args);
    Les fonctions fb_connection, fb_downres et fb_chksum se chargent de créer les trames.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    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 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par muad'dib Voir le message
    2º/ Un tableau contenant les différents ID et fonctions correspondantes (3 trames dans ce cas pour simplifier)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    const FORMATTER formatters[] = 
    {
       { ID_CONNECTION,           fb_connection  },
       { ID_DOWNLOAD,             fb_downres     },
       { ID_CHKSUM,               fb_chksum      }
    };
    3º/ Une fonction qui permet de recupérer un pointeur sur fonction au regard de l'ID de la trame
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void *get_formatter(const char idframe)
    {
       int i;
     
       for(i = 0; i < 3; i++)
          if(formatters[i].idframe == idframe)
             return formatters[i].function;
     
       return NULL;
    }
    Joli exemple mais le jour où tu passes à 4 trames, te faut modifier le code 1) dans ton tableau "formatters" et 2) dans ta boucle
    Avec un pointeur terminal tu évites ce pb

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    const FORMATTER formatters[] = 
    {
       { ID_CONNECTION,           fb_connection  },
       { ID_DOWNLOAD,             fb_downres     },
       { ID_CHKSUM,               fb_chksum      },
       { 0,                        NULL             }
    };
    Et la recherche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void *get_formatter(const char idframe)
    {
       FORMATTER *pt_frame;
     
       for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++)
       {
           if(pt_frame->idframe == idframe)
               return pt_frame->function;
     
       return NULL;
    }
    Le jour où tu passes à 4 trames, tu rajoutes juste une ligne dans le tableau "formatters" et pis c'est tout...
    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]

  8. #8
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Sauf que ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void *get_formatter(const char idframe)
    {
       FORMATTER *pt_frame;
     
       for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++)
       {
           if(pt_frame->idframe == idframe)
               return pt_frame->function;
     
       return NULL;
    }
    est faux!

    Un pointeur générique ne peut pointer sur une fonction.
    Après correction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void (*get_formatter(const char idframe))(void *, va_list)
    {
       FORMATTER *pt_frame;
     
       for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++)
       {
           if(pt_frame->idframe == idframe)
               return pt_frame->function;
     
       return NULL;
    }
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    typedef void (*MONTYPE)(void *, va_list);
     
    MONTYPE get_formatter(const char idframe)
    {
       FORMATTER *pt_frame;
     
       for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++)
       {
           if(pt_frame->idframe == idframe)
               return pt_frame->function;
     
       return NULL;
    }

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    209
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 209
    Par défaut
    merci les gars vous m'étonnez à chaque merci

  10. #10
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Joli exemple mais le jour où tu passes à 4 trames, te faut modifier le code 1) dans ton tableau "formatters" et 2) dans ta boucle
    Avec un pointeur terminal tu évites ce pb
    pas forcément :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void (*get_formatter(const char idframe))(void *, va_list)
    {
       for(int i = 0; i < (sizeof formatters)/(sizeof formatters[0]); i++)
          if(formatters[i].idframe == idframe)
             return formatters[i].function;
     
       return NULL;
    }

  11. #11
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Joli exemple mais le jour où tu passes à 4 trames, te faut modifier le code 1) dans ton tableau "formatters" et 2) dans ta boucle
    En effet c'est un problème que je n'avais pas trouvé comment résoudre. Bien pensé, ton astuce.
    Citation Envoyé par nicolas.sitbon
    Un pointeur générique ne peut pointer sur une fonction
    Pourtant gcc -Wall me l'accepte sans problèmes à la compilation et à l'exécution le code fonctionne. Mais c'est vrai que la déclaration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void (*get_formatter(const char idframe))(void *, va_list)
    est plus explicite.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i = 0; i < sizeof formatters; i++)
    Je ne suis pas sur que ce code fonctionne. Je testerai mais il me semble que j'avais essayé et que la valeur retournée est incorrecte.

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    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 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par muad'dib Voir le message
    En effet c'est un problème que je n'avais pas trouvé comment résoudre. Bien pensé, ton astuce
    Oaf c'est pas moi qui l'ai inventé (principe des strings en C)...
    Citation Envoyé par muad'dib Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i = 0; i < sizeof formatters; i++)
    Je ne suis pas sur que ce code fonctionne. Je testerai mais il me semble que j'avais essayé et que la valeur retournée est incorrecte.
    Ben oui, sizeof te donne le nombre d'octets, pas le nombre d'items...
    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]

  13. #13
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    oui pardon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i = 0; i < (sizeof formatters)/(sizeof formatters[0]); i++)
    et sizeof renvoi le nombre de bytes pas d'octet.

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    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 817
    Billets dans le blog
    1
    Par défaut
    [QUOTE=nicolas.sitbon;2634394]oui pardon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i = 0; i < (sizeof formatters)/(sizeof formatters[0]); i++)
    En théorie, cet algo de boucle fonctionne parfaitement. Cependant je ne l'aime pas parce que le jour où "formatters" devient un pointeur passé en paramètre sur un tableau de type FORMATTER, ben sizeof renvoie la taille du pointeur et non plus la taille du tableau et là
    Donc j'ai la faiblesse de penser que mon idée de null terminaison est la plus souple d'emploi et la plus facilement adaptable à toutes les situations

    Citation Envoyé par nicolas.sitbon Voir le message
    et sizeof renvoi le nombre de bytes pas d'octet.
    Bien vu (http://fr.wikipedia.org/wiki/Byte)
    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]

  15. #15
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Cependant je ne l'aime pas parce que le jour où "formatters" devient un pointeur passé en paramètre sur un tableau de type FORMATTER, ben sizeof renvoie la taille du pointeur et non plus la taille du tableau et là
    Oui j'y avais pensé mais dans le cas présent cela fonctionne, après tout dépend de l'utilisation qui en est faite.
    Cordialement.

  16. #16
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par yassinegoth Voir le message
    si on utilise des pointeurs pour mémoriser voir manipuler des variables par leurs adresses je me demande donc qu'il est l'interet des pointeurs sur des fcts
    Un autre exemple très répandu (valable dans tous les outils graphiques de nos jours)

    Un outil possède un objet "bouton", qui possède une "méthode" OnClick.

    Par définition, cet objet ne SAIT pas quelle est la fonction (si il y en a une) qui sera appelée, puisqu'elle dépend de l'utilisateur et de l'appli.

    Dans le code de l'objet, il y a donc un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ( If_There_Is_A_Function_For_OnClick(Objet) )
        Objet.OnClickFunction (...) ;
    J'ai utilisé cela à de nombreuses reprises (par exemple faie une biblothèque pour fabriquer des serveurs, où les actions sont identifiées, mais pas la réalisation : par exemple avoir plusieurs serveurs simultanés sur des bases gérées par des outils différents), mais aussi des applis avec des "plugins", etc etc..

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

Discussions similaires

  1. pointeur de tableau pour fonction void
    Par giovedy dans le forum C
    Réponses: 4
    Dernier message: 01/08/2012, 18h18
  2. pointeur tableau arg fonction
    Par guitz dans le forum Débuter
    Réponses: 3
    Dernier message: 01/11/2009, 11h29
  3. Passage de tableau à une fonction par pointeur
    Par progfou dans le forum C++
    Réponses: 15
    Dernier message: 23/02/2007, 11h45
  4. Réponses: 8
    Dernier message: 10/03/2006, 17h28
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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