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 :

Retours multiples de fonctions : où déclarer les variables de réponses ?


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 21
    Points : 18
    Points
    18
    Par défaut Retours multiples de fonctions : où déclarer les variables de réponses ?
    Bonjour,

    je me posais la question de où déclarer des variables (structures, tableaux, ...) permettant à mes fonctions de renvoyer plusieurs informations.

    Exemple (simplifié):
    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
    int main()
    {
       while(1)
       {
         fonction1();
       }
    }
     
    void fonction1(void)
    {
         int i;
         for(i=0;i<100;i++)
         {
             fonction2(tab_resultat, i)
    //ici, on exploite tab_resultat
         }
    }
     
    fonction2(int *tab_resultat, int entree)
    {
        int j;
        for(j=0;j<100;j++)
        {
             tab_resultat[entree]=(j==entree);
         }
    }
    Ma question est donc où déclarer tab_resultat (tableau de 100 int), sachant que tab_resultat n'est exploité que dans l'itération en cours de la boucle for de fonction1: je vois 3 solutions, chacune avec ses avantages et inconvénients:
    -on déclare tab_resultat au début de fonction1 : inconvénient : on recrée le tableau à chaque appel de fonction1 (perte de temps)
    -on déclare tab_resultat dans le main et on le passe en argument à fonction1 : avantage, on ne déclare qu'une fois le tableau; inconvénients : on doit l'écrire en paramètres pour 2 fonctions : perte de temps et alourdissement du code + ralentissement (plus de données à mettre en pile d’exécution)
    -on crée une variable globale : avantages : on ne doit jamais le passer en argument d'une fonction, et dans certains cas (ex : un int), on peut manipuler l'objet sans avoir à transmettre un pointeur dessus à la place, mais on "s'encombre" avec de nombreuses variables globales.

    NB : en pratique, toute mes fonctions ne sont pas dans le même fichier et il y en a parfois plus d'imbriquées
    NB: j'ai pris ici un exemple avec un tableau, mais il peut s'agir de tout autres objets, de l'entier à une structure compliquée, ou a plusieurs objets différents (fonctions à plus d'arguments).


    Ma question est donc la suivante : laquelle des méthodes est la meilleure (ou encore une autre à laquelle je n'aurais pas pensé)?

    En vous remerciant par avance
    Sandro11

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Bonsoir.

    À priori je fais tout mon possible pour m'interdire de déclarer des variables en globale. Ce n'est pas tant que ce soit interdit. C'est surtout que si le code devient important il y a des risques de modifications de ces variables n'importe où. Le déboguage devient alors un vrai casse-tête.

    Comme tu l'as montré dans ton code exemple je déclarerais le tableau dans le main et le propagerais dans les fonctions en paramètre. Seul le pointeur est propagé. Je ne pense pas que les performances en soient affectées.

    D'autres pourront sûrement être plus précis que moi sur ce sujet .

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 21
    Points : 18
    Points
    18
    Par défaut
    Merci,
    pour mon programme actuel, c'est ce que j'ai commencé à faire (pour d'autres, ça a été les variables globales).
    Le seul problème, c'est que quand on a plein de variables de types différents à modifier, ça devient vite lourd, surtout pour la première fonction appelée (si par exemple il y a aussi fonction2bis, fonction2ter, ... appellées par fonction1, avec à chaque fois 4-5 variables à modifier et même pas toujours les mêmes.

    Après, est-ce que ça peut valoir le coup de distinguer selon le type de variables à modifier (par exemple, un int, on le déclare à chaque fois dans fonction1 mais un tableau à 100 000 éléments, on le déclare dans le main)?

    En vous remerciant par avance
    Sandro

  4. #4
    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 sandro11 Voir le message
    Après, est-ce que ça peut valoir le coup de distinguer selon le type de variables à modifier (par exemple, un int, on le déclare à chaque fois dans fonction1 mais un tableau à 100 000 éléments, on le déclare dans le main)?
    Absolument pas. Tu définis (et non "déclare") ta variable là où tu en as besoin. A toi de t'organiser pour éviter 45 variables par fonctions. Si par exemple tu as un gros projet dans lequel tu veux avoir un environnement paramétrable, comme par exemple le dossier de travail, le dossier temporaire, le nombre de sous-fenêtres max, le nombre de décimales à afficher, un flag "mode développement" dans lequel tu affiches plus d'infos qu'en mode normal, l'adresse du serveur bdd, son n° de port (exemple pris à partir d'un cas réel chez-moi) et que devoir te trimballer tous ces éléments entre fonctions ça te gonfle (c'est compréhensible) alors rien ne t'interdit de définir une structure contenant tous ces éléments. Ensuite te suffit de passer l'adresse de cette structure (une seule variable) à tes fonctions qui en ont besoin, lesquelles auront alors automatiquement accès à tous les éléments de la structure...
    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]

  5. #5
    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
    Je ferai un raisonnement assez différent. Tu parles de performances à l'appel et de lourdeur visuel du code ; a contrario, je parlerais plutôt de sémantique de chaque fonction. Que fait la fonction f() ? De quoi a t-elle besoin pour travailler ? Quelles valeurs retournent (via return ou des paramètres in/out) ? A partir de ça, tu écris des fonctions et une fois les fonctions écrites, alors tu les assembles pour faire un programme. Une telle approche est souvent la meilleure pour écrire des programmes lisibles et modulables. C'est seulement si les performances semblent mauvaises qu'on optimise.

    Passer un ou deux ou trois paramètres à une fonction ne fait pas forcément une différence de performances importante, il y a beaucoup de choses à optimiser avant d'en arriver là. D'ailleurs, je ne parierai pas que "déclarer une variable dans le main() et passer à fonction1()" soit plus rapide que "déclarer à chaque fois la variable dans fonction1()". Cela peut dépendre de l'architecture, du type de la variable, car il est difficile sans regarder l'assembleur de savoir comment le compilateur va mettre et enlever la variable des registres pour faire les appels de fonctions. A ce petit jeu, la variable globale sera sans doute lente car il me semble peu probable (sauf dans un programme simple) de pouvoir mettre une variable globale dans un registre (sinon, finis les accès multithreads).

    S'il y a énormément de paramètres, Sve@r a totalement raison de passer par une structure (ou des structures). Penser à utiliser des pointeurs pour passer une structure en paramètres si elle est grosse car elle est copiée sur la pile.

  6. #6
    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
    Citation Envoyé par sandro11 Voir le message
    Le seul problème, c'est que quand on a plein de variables de types différents à modifier, ça devient vite lourd, surtout pour la première fonction appelée
    Citation Envoyé par Bktero Voir le message
    Je ferai un raisonnement assez différent. Tu parles de performances à l'appel et de lourdeur visuel du code ; a contrario, je parlerais plutôt de sémantique de chaque fonction. Que fait la fonction f() ? De quoi a t-elle besoin pour travailler ? Quelles valeurs retournent (via return ou des paramètres in/out) ? A partir de ça, tu écris des fonctions et une fois les fonctions écrites, alors tu les assembles pour faire une programme. Une telle approche est souvent la meilleure pour écrire des programmes lisibles et modulables.
    Totalement d'accord. A rajouter aussi que généralement une fonction poursuit un but fermé. C'est à dire que quand tu découpes ton travail en une multitude de petites taches, chaque tache est alors dévolue à une fonction laquelle l'exécutera en entier. Dans ce genre de découpage, les diverses fonctions ont alors besoin de très peu d'éléments venus de l'extèrieur et ont alors peu de chance de devoir déclarer 36 paramètres distincts. T'as qu'à regarder les fonctions de la librairie standard. Rares sont celles qui ont besoin de plus de 4 paramètre. A froid comme ça, la plus complexe qui me vient à l'esprit est qsort() laquelle n'a besoin que du tableau à trier, le nombre d'éléments, la taille d'un élément et l'adresse de la fonction dédiée à la comparaison de 2 éléments. Donc dis-toi bien que si tu commences à avoir "plein de variables" à passer à ta fonction c'est que quelque part t'as probablement mal organisé ton travail.

    Autre exemple: si tu crées un jeu de rôle et que tu veux écrire la fonction qui organise un combat entre 2 personnages, t'auras le choix entre
    • envoyer à ta fonction les 15 caractéristiques du personnage 1 et les 15 caractéristiques du personnage 2 (30 paramètres)
    • avoir au préalable définit une structure englobant les caractéristiques générales d'un personnage quelconque puis envoyer à ta fonction l'adresse de la structure concernant le personnge 1 et l'adresse de la structure concernant le personnge 2 (2 paramètres).

    A ton avis, quelle solution a été "mal pensée" ???
    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]

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 21
    Points : 18
    Points
    18
    Par défaut
    Merci beaucoup.

    Donc si j'ai bien compris, je définis chaque variable le plus tard possible, puis je la transmet en paramètre.
    Si j'ai un même ensemble de (beaucoup) de variables que je dois envoyer à plusieurs fonctions différentes (emboîtées ou exécutées successivement), alors je crée une structure et je transmet un pointeur sur celle-ci.
    Si je commence à avoir vraiment trop de données à transmettre (pour l'instant j'ai au maximum 6 entrées/sorties), il faut vérifier si le découpage en fonction est bien pensé (d'ailleurs, si quelqu'un connait un tuto la dessus, je serais preneur (mes cours d'informatiques en prépa n'abordaient pas de véritables projets (100 lignes max), et les tuto de programmation se tiennent généralement à la syntaxe et à des exemples courts)).

  8. #8
    Membre actif

    Homme Profil pro
    autodidacte
    Inscrit en
    Mars 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : autodidacte

    Informations forums :
    Inscription : Mars 2011
    Messages : 95
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par sandro11 Voir le message
    il faut vérifier si le découpage en fonction est bien pensé (d'ailleurs, si quelqu'un connait un tuto la dessus, je serais preneur
    Je te conseille de lire ce tuto :
    http://alexandre-laurent.developpez....programmation/

    Ce que j'en ai retiré:
    - faire un programme fonctionnel, PUIS penser à optimiser
    - faire de petites fonctions
    - faire du code clair (structure et noms)
    - plus les fonctions sont simples, plus on gagne de temps en tests

    Bien à toi.

    Olivier
    Toujours à adapter le problème à la structure de la machine, mais se soigne pour faire l'inverse.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 21
    Points : 18
    Points
    18
    Par défaut
    merci

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

Discussions similaires

  1. Ne pas déclarer les variables
    Par Loki83 dans le forum Macros et VBA Excel
    Réponses: 20
    Dernier message: 14/11/2008, 15h27
  2. retour multiple de fonction
    Par danathane dans le forum Langage
    Réponses: 2
    Dernier message: 13/11/2008, 12h14
  3. Réponses: 2
    Dernier message: 05/05/2008, 17h25
  4. déclarer les variables
    Par koKoTis dans le forum C++
    Réponses: 2
    Dernier message: 29/12/2006, 14h40
  5. Réponses: 4
    Dernier message: 20/04/2006, 02h56

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