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 :

fonction avec un nombre non défini de paramètres


Sujet :

C

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2013
    Messages : 15
    Points : 6
    Points
    6
    Par défaut fonction avec un nombre non défini de paramètres
    salut les gurus du c

    j'aimerais bien pouvoir écrire une fonction qui pourrait accepter un nombre quelconque de paramètres, comme printf. Le détail qui fait que ça devient un problème c'est que j'aimerais aussi que cette fonction marche aussi si on ne lui en donne pas. J'ai vu que c'est pas possible d'utiliser
    Si ça peut aider ma fonction prendrait un nombre de 0 à plusieurs paramètres de type pointeur puis le dernier sera NULL sauf dans le cas où il y en a pas et si je peux m'en passer grace a vos conseils de gurus ce serait encore mieux

    merci

  2. #2
    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
    Pour "un ou plusieurs" je connais les va_list et va_args (ce que printf utilise).

    Mais pour aucun... euh... je suppose que la va_list sait le gérer, à vérifier ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Bonjour,

    réponse courte : tu ne peux pas.
    Tu dois toujours avoir au moins un paramètre pour utiliser va_start. Donc la version sans aucun paramètre est impossible en utilisant stdarg.h.
    Ce que tu peux faire de plus proche est quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void fonction(type* param1, ...);
    Si param1 n'est pas NULL alors tu utilises les macros va_* pour accéder aux autres paramètres, en supposant qu'un paramètre NULL indique toujours la fin de la liste.

    réponse un peu plus longue: tu peux essayer de te débrouiller avec des macros. C'est souvent un peu plus compliqué, un peu plus casse gueule mais ça peut fonctionner.
    Avec C99 par exemple tu as les variadic macros, et avec gcc il y a une gestion des virgules comme séparateur de paramètres. Dans un premier temps lis la doc pour comprendre comment ça fonctionne.

    Donc après avoir ingéré la doc, on peut imaginer écrire l'implémentation de ta fonction avec comme premier paramètre un paramètre bidon, la liste effective des paramètres suit et se termine par NULL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void fonction_impl(char* dummy, ...)
    {
      va_list vl;
      char* param;
      va_start(vl,dummy);
      while ( (param=va_arg(vl, char*)) )
        puts(param);
      va_end(vl);
    }
    La macro est ensuite simple à construire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define fonction(...) {                                         \
                            fonction_impl("", ##__VA_ARGS__, NULL); \
                          } while(0)
    Un main pour tester ça pourrait-être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
     
      fonction();
      fonction("1","2","3");
     
      return 0;
    }
    Comme je te l'ai dit, ce n'est pas une méthode que je te recommande ...

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2010
    Messages : 173
    Points : 485
    Points
    485
    Par défaut
    Le C remonte à longtemps mais pourquoi tu ne passes pas un tableau en paramètre ?

  5. #5
    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
    Même si la dernière réponse sent le troll avec le "Le C remonte à longtemps" (ou c'est moi qui interprète mal, et fozzeuh voulait juste dire qu'il n'en avait pas fait depuis longtemps ), c'est vrai que c'est plutôt une bonne idée...

    Mettre un tableau ou un NULL pointer facilitera grandement les choses !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2010
    Messages : 173
    Points : 485
    Points
    485
    Par défaut
    Citation Envoyé par Metalman Voir le message
    Même si la dernière réponse sent le troll avec le "Le C remonte à longtemps" (ou c'est moi qui interprète mal, et fozzeuh voulait juste dire qu'il n'en avait pas fait depuis longtemps ), c'est vrai que c'est plutôt une bonne idée...
    Non , non ce n'est pas un troll , j'en ai pas fais depuis longtemps.

  7. #7
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Il n'y avait pas la possibilité de créer 2 fonctions de meme nom, une sans paramètre et l'autre avec -> le programme se chargeait de faire la différence?

  8. #8
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2010
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2010
    Messages : 173
    Points : 485
    Points
    485
    Par défaut
    Citation Envoyé par Bysbobo Voir le message
    Il n'y avait pas la possibilité de créer 2 fonctions de meme nom, une sans paramètre et l'autre avec -> le programme se chargeait de faire la différence?
    Tu dois pouvoir (en C je sais pas) mais l'auteur veut absolument un nombre indéfinie de paramètre.

  9. #9
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Le C ne gère pas la surcharge de fonction à l'inverse de certains langages (comme le C++ par exemple).

  10. #10
    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
    @fozzeuh : mon esprit trollesque s'est donc excité pour rien ! Excuse-moi !

    Le C ne gère pas 2 fonctions du même nom, mais le C++ oui

    EDIT : imperio en premier...
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  11. #11
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Bon j'osais pas la mettre parce que je ne sais meme pas si c'est faisable mais bon je me lance.
    Si tu pars sur le fait que ce que l'utilisateur te passe en paramètre est 1 seule et unique chaine de caractère et que tu la sépares toi meme suivant les ","?

    Je ne suis pas un as mais j'adore le bricolage alors bon, j'essaye d'aider

  12. #12
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    tu peux peut-être nous dire ce que doit faire ta fonction, pour qu'on arrete de spéculer dans le vide.

    Par ailleurs, si tous les arguments sont indépendants, un tableau, ou mieux, une version à un argument et une boucle.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  13. #13
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Moi j'aimerai bien savoir, si ta fonction peut être appelée sans paramètres, comment fait-elle pour savoir avec combien de paramètres elles a été appelée ?

    Si les fonctions variadiques ont forcément un premier paramètre "fixe", c'est que ce premier paramètre est nécessaire pour savoir combien de paramètres variables suivent.

  14. #14
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2013
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Merci à tout le monde pour les réponses si rapides !
    @letrnel
    maintenant on fait que la conception encore et on a un type TTask avec un tableau de TTask* qu'on a definit comme ça TTask* Tasks[MAXTASK]. Dans le code on va avoir besoin d'utiliser ses tasks alors on a dabord pensé à écrire une fonction doTask avec comme paramètre le task. Mais comme on doit souvent en enchainer plus que un on a pensé utiliser une fonction avec un nombre variable de paramètres comme printf. C'était pour éviter de copier toujours le même code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    initialisation();
    doTask(Tasks[bidule1]);
    doTask(Tasks[bidule8]);
    doTask(Tasks[bidule13]);
    finalisation();
    Le nombre de tasks et les tasks est différent plus ou moins à chaque fois mais même si y a pas de tasks il faut faire initialiasation et finalisation
    Alors on s'est dit que c'est bien d'avoir une fonction avec un nombre de paramètre pas défini comme printf qui fait initialisation, finalisation et si y faut les doTask. ça fait que le code du dessus donne un simple doTasks(tasks[bidule1],tasks[bidule8],tasks[bidule13]) et pis on s'est dit que pas de tasks ça donne doTasks() qui fait que intialisation() et finalisation().

    c'est bête comme conception ? je suis assez claire ou je me plante ?

  15. #15
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2013
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par fozzeuh Voir le message
    Le C remonte à longtemps mais pourquoi tu ne passes pas un tableau en paramètre ?
    parce que dans ce cas je dois créer le tableau avant et que ça me fait autant à taper que d'apeler tout le code que je veux remplacer

  16. #16
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2013
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    @kwariz je crois que je vais faire comme ta première idée, mais c'est nulle d'avoir à mettre NULL pour dire qu'y a pas de tasks.

  17. #17
    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,

    Si tu connais le nombre de task et qu'il n'y en a pas beaucoup.
    Tu peux faire un champ de bit.
    Comme ça ta fonction donnerais ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    doTask(TTASK**, int flag)
    Le soucis est que tu es limité à 32 task dans le cas d'un int

    Ou alors faire une liste chaînée des taches a exécuter.

  18. #18
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Votre problème est dans votre conception.
    Vos taches ne sont pas anonyme, donc il faut les personnifier.
    En plus du tableau (utile pour le parcours?), il vous faudrait un identifiant ou une référence directe (un pointeur, donc)

    Autre usage envisageable: doTasks(tasks, bidule1, bidule8, bidule13);.

    La fonction aurait alors pour signature void doTasks((Task*)[], ...);, et son vargs serait un ensemble d'entier indexant tasks.
    Cela dit, cela reste un bon moyen de taper en dehors du tableau.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  19. #19
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par joliette Voir le message
    @kwariz je crois que je vais faire comme ta première idée, mais c'est nulle d'avoir à mettre NULL pour dire qu'y a pas de tasks.
    C'est pas «nul» c'est classique. Si ça te dérange tu peux renommer le NULL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #define NO_TASKS NULL
    #define END_OF_TASKS NULL
     
    fonction(NO_TASKS);
    fonction(t1,t2,t3,..., END_OF_TASKS);

  20. #20
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2013
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par leternel Voir le message
    Votre problème est dans votre conception.
    Vos taches ne sont pas anonyme, donc il faut les personnifier.
    je comprends pas ... comment ça personnifier ?

    En plus du tableau (utile pour le parcours?), il vous faudrait un identifiant ou une référence directe (un pointeur, donc)

    Autre usage envisageable: doTasks(tasks, bidule1, bidule8, bidule13);.
    j'ai un peu simplifié le problème parce qu'il y a qu'un tableau pour l'instant mais ça peut bouger. C'est pour ça qu'on préfère passer directement les pointeurs que les index, ça sera plus simple si on a plus de tableau après, non ?
    Mais si je passe les index pour dire qu'il y en a pas je passe -1 et c'est comme le NULL alors, non ?

    La fonction aurait alors pour signature void doTasks((Task*)[], ...);, et son vargs serait un ensemble d'entier indexant tasks.
    Cela dit, cela reste un bon moyen de taper en dehors du tableau.
    ouais c c'est pas top pour empécher ça lol

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Une méthode void avec un nombre non prédéfini de paramètres
    Par ROUGE87 dans le forum Général Java
    Réponses: 10
    Dernier message: 26/04/2011, 17h13
  2. Réponses: 3
    Dernier message: 05/09/2006, 00h47
  3. Réponses: 7
    Dernier message: 19/05/2006, 16h47
  4. Réponses: 6
    Dernier message: 10/08/2005, 11h36
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 13h39

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