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 :

Passer une fonction en paramètre


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2012
    Messages : 42
    Points : 40
    Points
    40
    Par défaut Passer une fonction en paramètre
    Bonjour tout le monde,

    J'ai un souci super urgent, je suis débutant en C et je voudrais savoir comment passer une fonction en paramètre en C. Je m'explique : Voici mon code :
    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
    int main(int argc, char *argv[]) {
     
        if (argc != 2) {
            printf("Passez les arguments à la fonction...\n");
            return EXIT_SUCCESS;
        } 
     
        char* cheminimage = argv[1];
     
        //on affiche l'image pour être sur d'avoir la bonne image
        pgmimage* image = creationimage(chemin);
        if(image == NULL) {
            printf("Impossible de créer l'image\n");
        }
     
        imagecopie(image, "test_save1.pgm");
     
        luminière(image, 40, "test_save2.pgm");
     
     
        return EXIT_SUCCESS;
    }
    Je m'explique, voilà la fonction doit être appelé comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./ main "cheminimage" "filtre(40)"
    Voilà j'ai passé en paramètre à argv[1] le chemin de l'image comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* cheminimage = argv[1];
    et ça marche et je voudrais passer à argv[2] ma fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "luminière(image, 40, "test_save2.pgm)"
    Pour qu'à ma compilation j'appelle mon main de cette façon, c'est super urgent Merci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./main "image.pgm" "lumière(40)"

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Je pense que tu t'y prend de la mauvaise manière.
    Essaye de t'inspirer des autres commandes qui existent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    commande valeur -nomOption valeurOption
    Ainsi il te suffit juste de lire argument par argument.
    Si l'argument commence par un "-", tu va lire une option et en fonction de l'option, tu vas traiter un ou plusieurs autres arguments et les placer dans des variables.
    Pour mettre des valeurs par défaut, il te suffit juste d'initialiser tes variables au début de ton programme.

    Après pour convertir la chaîne de caractère, tu peut regarder du côté de sscanf ou de strtol/ll/d/q/etc...

  3. #3
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    À moins de détourner le problème, tu ne peux pas modifier le code machine de ton programme à l'exécution. La seule chose que tu peux faire est d'en modifier le flot d'exécution, en utilisant, par exemple, les branchements conditionnels. Typiquement, ici, tu peux comparer la fonction passée en ligne de commande avec celles définies dans ton programme. Ci-après une manière de procéder. On peut commencer par considérer une fonction analyse, qui, à partir de la chaîne de caractère constituant les arguments en ligne de commande, retourne une structure contenant les différents champs attendus. Ppour éviter de réinventer la roue, tu peux également utiliser des bibliothèques de sur-couche logicielle comme getopt, qui permettent de gérer spécifiquement les arguments en ligne de commande. Imaginons par exemple le programme HelloWorld, qui prend un identificateur de fonction en paramètre : pour hello, on exécute la fonction hello, et pour world, on exécute la fonction world.

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    /* GNU Coding Standards */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef void fun (void);
     
    static void
    world (void)
    {
      puts ("World");
    }
     
    static void
    hello (void)
    {
      puts ("Hello");
    }
     
    static fun *
    analyse (const char *argline)
    {
      fun *ret = NULL;
     
      if (strcmp (argline, "hello") == 0)
        {
          ret = hello;
        }
      else if (strcmp (argline, "world") == 0)
        {
          ret = world;
        }
     
      return ret;
    }
     
    static void
    usage (const char *program_name, int status)
    {
      if (status != EXIT_SUCCESS)
        {
          printf ("Usage: %s FUN\n", program_name);
        }
     
      exit (status);
    }
     
    int
    main (int argc, char **argv)
    {
      fun *exec_fun = NULL;
     
      if (argc == 2)
        {
          exec_fun = analyse (argv[1]);
        }
      else
        {
          usage (argv[0], EXIT_FAILURE);
        }
     
      if (exec_fun != NULL)
        {
          exec_fun ();
        }
      else
        {
          usage (argv[0], EXIT_FAILURE);
        }
     
      return 0;
    }
    À ce propos, il y a un problème dans ton nommage des identificateurs ; luminière n'est en effet pas un identificateur correct en langage C.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    bonjour,

    Je rejoins l'idée des options dans la ligne de commande ensuite tu peux faire un tableau de structure avec des pointeur sur fonction

    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
    33
     
     
    typedef struct s_fct
    {
       char opt;
       fct   fonction;
    } t_fct =
     
    typedef void (*fct)(arg);
     
    t_fct mesFct[] = {{'a', &fct1}, {'b', &fct2}, NULL};
     
    int maint(int argc, int** argv)
    {
          char* path;
          int count;
          int count2;
     
          if (argc > 2)
             return -1;
          path = argv[1];
     
         for (count = 2; argv[2][count] != '\0'; count++)
          {
           for (count2 = 0; mesFct[count2] != NULL && count2 > 0; count2++)
              if(mesFct[count2].opt == argv[2][count])
              {
                  (*(mesFct[count2]).fct)(path);
                  count2 = -1;
              }
          }
     
    }

    A revérifier mais dans l'idée c'est un truc dans le style

  5. #5
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Le problème du tableau et de la fonction analyse de lucas, c'est que toutes les fonctions doivent avoir la même signature. C'est assez contraignant si on veut gérer un minimum d'options.
    Plus tu pédales moins fort, moins t'avances plus vite.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par Pouet_forever Voir le message
    Le problème du tableau et de la fonction analyse de lucas, c'est que toutes les fonctions doivent avoir la même signature. C'est assez contraignant si on veut gérer un minimum d'options.
    Si on ne gère que des options, il suffit juste de faire une structure "Options" contenant toutes les variables nécessaires (et pouvant même contenir d'autres structures).

    Sinon utiliser un tableau est très lent dans ce cas là.
    Il vaut mieux passer par un arbre équilibré trié sur le nom de l'option.

  7. #7
    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
    Ou, si c'est statique, un tableau trié et une recherche dichotomique. Voir fonction bsearch() dans la bibliothèque standard du C.

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    typedef struct s_options
    {
    	/*...*/
    } t_options;
     
    typedef void (*fct)(t_options const *arg);
     
    typedef struct s_fct
    {
    	char const *nom;
    	fct const fonction;
    } t_fct;
     
    /*Fonction de comparaison*/
    int compare_cle_fct(const void *pcvCle, const void *pcvFct)
    {
    	char const *cle = pcvCle;
    	t_cft const *fct = pcvFct;
    	return strcmp(cle, fct->nom);
    }
     
    /*Fonction de recherche dans un tableau de fct*/
    t_fct const *bsearch_fct_c(
     char const *nom,
     t_fct const *fonctions,
     size_t nbFonctions
    )
    {
    	return bsearch(nom, fonctions, nbFonctions, sizeof *fonctions, compare_cle_fct);
    }
     
     
    /*
    Variables globales et fonctions les utilisant
    */
    /*Attention, ce tableau doit être trié*/
    static t_fct const g_mesFct[] = {{"fct1", &fct1}, {"fct2", &fct2}};
    static size_t const g_nbFonctions = sizeof g_mesFct / sizeof g_mesFct[0];
     
    /*Fonction de recherche dans le tableau global de fct*/
    t_fct const * GetFonction(char const *nom)
    {
    	return bsearch_fct_c(nom, g_mesFct, g_nbFonctions);
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    Et en ajoutant une structure d'options tu peux mettre un maximum d'option tout en standardisant ta prise de paramètre, voir plusieurs structures avec en prise de paramètre un void*.

    C'est pas d'un propreté exemplaire mais c'est pas mal.

    Ensuite ça dépend du type d'option
    si ce n'est pas des valeurs mais un enchaînement d'options tu peux te rabattre sur des champs de bits.

Discussions similaires

  1. Réponses: 16
    Dernier message: 26/05/2009, 13h32
  2. Passer une fonction en paramètre, sans delegate
    Par deejay2221 dans le forum C#
    Réponses: 8
    Dernier message: 26/03/2009, 20h22
  3. Réponses: 15
    Dernier message: 02/08/2007, 11h17
  4. Passer une fonction en paramètre ...
    Par Freeze dans le forum C++Builder
    Réponses: 2
    Dernier message: 14/10/2005, 16h51
  5. [Conception] Passer une fonction en paramètre
    Par pejay dans le forum Langage
    Réponses: 9
    Dernier message: 09/12/2004, 13h58

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