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 qui retourne plusieurs valeurs ! [FAQ]


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2003
    Messages : 216
    Par défaut Fonction qui retourne plusieurs valeurs !
    Bonjour,

    J'aimerais savoir si c'est possible de faire une fonction qui retourne 3 valeurs: a[0], a[1] et a[2].

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int fonction(int chiffre){
      int a[3];
     
      a[0] = chiffre+1;
      a[1] = chiffre+2;
      a[2] = chiffre+3;
     
      return(????); //Faut mettre quoi ?
    }
    void main(void){
      int b[3];
      //Comment récupérer les 3 valeurs de la fonction dans le tableau b[3] ?
    }
    Merci d'avance...
    ++

  2. #2
    Rédacteur
    Avatar de Giovanny Temgoua
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    3 830
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 3 830
    Par défaut
    Une fois j'ai cru voir ce suejt traité dans ce forum.

    Sinon, LA valeur de retour est celle que tu as précisée entre autre int dans ton cas...

    Il n'est pas possible de retourner plus d'une valeur. Cependant, tu peuxx toujours trouver une astuce pour contourner le problème... Par exemple, tu peux définir comme type de retour un pointeur sur un tableau par exemple...

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Par défaut
    Salut!!!
    Ce que tu peux faire, c'est passer des variables à la fonction par référence, c'est-à-dire que les variables passées en paramètres seront modifiées par la fonction.

    Voici un petit exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void fonction(int &n1, int &n2, int &n3, int chiffre)
    {
      n1 = chiffre + 1;
      n2 = chiffre + 2;
      n3 = chiffre + 3;
    }
    Et on l'appel comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int a, b, c;
    fonction(a, b, c, 10);
     
    cout << "a: " << a << "\n";
    cout << "b: " << b << "\n";
    cout << "c: " << c << "\n";
    La sortie est:

    a: 11
    b: 12
    c: 13


    Voila, c'était une possibilité.

    @++

    R@f

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Je pense aussi que c'est la solution la plus propre.
    Sinon, également possible (en vrac qui me viennent en tête) :
    * mettre ton "int [3]" dans une structure et renvoyer cette structure (copie des 3 int)
    * renvoyer un tableau alloué dynamiquement, je déconseille assez l'utilisation des new[] surtout quand on est novice
    * même chose mais en enveloppant le tableau dans un truc qui fonctionne comme auto_ptr<>, mais pour les buffers/tableaux => limite les risques de mauvaise manip de mémoire ; regarder chez boost ou STLsoft (je ne sais plus lequel des deux), ils proposent une telle classe.
    * utiliser une classe qui est une abstraction sur les tableaux comme
    - std::vector<>, qui permet d'avoir une taile de la zone contenue variable ; par contre copie des 3 éléments aussi je le crains
    - std::val_array<> : avec elle, il doit y avoir moyen de limiter les copies inutiles (à condition d'en avoir une implémentation récente et peut-etre de bidouiller un chouila), et en plus elle est adaptée aux petits calculs mathématiques.

    Ca, c'était pour renvoyer un tableau. Pour plusieurs éléments hétérogènes, tu les mets dans une structure. Par contre pour ce qui est d'éviter les copies inutiles, c'est un problème intéressant auquel il existe des solutions (chercher un article fort intéressant (pas un article pour débutants) d'Andrei Alexandrescu sur CUJ qui présente une technique qu'il a baptisée MOJO) ; et regarder le support de la RVO pour votre compilateur.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Bonjour

    Citation Envoyé par Luc Hermitte Voir le message
    Pour plusieurs éléments hétérogènes, tu les mets dans une structure.
    Pas forcément. C++11 a apporté le support des tuples, qui servent notamment à faire ce genre de choses sans avoir à définir de structure. Exemple:

    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
    #include <iostream>
    #include <string>
    #include <tuple>
     
    std::tuple<std::string, int, double> f() {
      return std::make_tuple(std::string("Roger"), 5, 1.2);
    }
     
    int main() {
      std::string val1;
      int val2;
      double val3;
      std::tie(val1, val2, val3) = f();
      std::cout << val1 << " " << val2 << " " << val3 << std::endl;
      return 0;
    }
    D'un point de vue purement technique, on ne renvoie qu'une valeur, un tuple. D'un point de vue sémantique, on renvoie trois valeurs distinctes qui n'ont pas nécessairement de relation entre elles.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    C++11
    10/01/2004, 14h13


    Btw, utiliser les "anciens procédés" est parfois obligatoire. Et fonctionnent aussi. Hélas, toutes les entreprises n'utilisent pas les dernières technos.
    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.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    En effet, je n'avais pas vu qu'il s'agissait d'un déterrage en règle ^^. Du reste, je ne contredis pas la validité de l'ancienne méthode. Il y a même des boîtes qui interdisent l'usage de la STL (pour du dev destkop, je parle pas de code industriel embarqué) :p.

  8. #8
    Nouveau candidat au Club
    Inscrit en
    Juillet 2003
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 2
    Par défaut
    Salut,
    J'ai le meme probleme que casala. et Luc propose une solution avec un tableau alloué dynamiquement...
    Est ce que je pouurais avoir plus de precision sur la façon de proceder.

    est ce que c un truc de ce genre?


    double tab = new ???

    ??? getTab() { return tab;}
    Merci pour vos lumiere...
    Djacko

  9. #9
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Luc propose une solution avec un tableau alloué dynamiquement...
    Luc déconseille la solution à base de tableau dynamique.

    Sinon, ça donne quelque chose de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    double* Fonction()
    {
       double* Tab = new double[nombre_de_resultats];
       // ...
     
       return Tab;
    }

  10. #10
    Nouveau candidat au Club
    Inscrit en
    Juillet 2003
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 2
    Par défaut
    Ah ok j'avais mal compris

  11. #11
    Membre averti
    Inscrit en
    Février 2011
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 22
    Par défaut questions sur les solutions proposées
    Bonjour,

    je débute en C++. Après une recherche sur le web , je suis tombé sur cette discussion, qui date de 2004, mais qui visiblement est encore pertinente puisqu'elle apparait en haut dans les résultats de recherche.

    J'ai une question par rapport à ce qui a été dit, par Luc Hermitte le 10/01/04 :

    "std::vector<>, qui permet d'avoir une taille de la zone contenue variable ; par contre copie des 3 éléments aussi je le crains"
    Au niveau de la crainte : C'est à dire que les 3 éléments de retour sont créés puis passés ensuite à des variables au niveau de l'appel de fonction ? C'est-à dire : par exemple, on a :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int retour f1() {
    retour=3;
    return retour; 
    }
    et dans le main:
    Alors on a 2 entiers qui sont créés : retour et a.

    En revanche si on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void f1 (int &retour) {
    retour=3;
    }
    puis dans le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a;
    int &b=a;
    f(b);
    Alors dans ce deuxième cas on ne crée qu'un objet de type int : a .
    C'est ce que voulait dire Luc Hermitte ?


    2ème point : je trouve qu'au niveau de la lecture c'est pas super agréable: on passe en argument ce qu'on aimerait avoir en sortie : c'est bizarre comme logique, non ?

    MErci pour vos retours !

    PS : désolé, je n'ai pas encadré le code par des balises adaptées, je ne vois pas ces balises dans l'interface d'édition de message !

  12. #12
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par olap75 Voir le message
    C'est ce que voulait dire Luc Hermitte ?


    2ème point : je trouve qu'au niveau de la lecture c'est pas super agréable: on passe en argument ce qu'on aimerait avoir en sortie : c'est bizarre comme logique, non ?
    Pour le code, il y à l'icone #, ou les balises [ code] [ /code]

    Sinon, oui dans l'idée c'est ce qu'il voulait dire. Dans tes exemples par contre, il n'y aura pas de copie.

    Pour les arguments par référence, c'est assez fréquent en C++, une habitude à prendre mais rien de bizarre.
    Une autre solution qui n'a pas été donné c'est l'utilisation de tuple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    std::tuple<int, int, int> foo(int n) {
       return std::make_tuple(n+1, n+2, n+3);
    }
     
    auto t = foo(42);
    assert(std::get<0>(t) == 43);
    assert(std::get<1>(t) == 44);
    assert(std::get<2>(t) == 45);

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Depuis 2004 ils ont ajouté la move-semantic, et le retour ne se fait plus forcément par copie mais peut utiliser ce nouveau procédé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a;
    int &b=a;
    f(b);
    On écrira
    On peut aussi utiliser un pointeur.

    Une autre solution qui n'a pas été donné c'est l'utilisation de tuple
    Ou bien "à l'ancienne" : une structure.
    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.

  14. #14
    Membre averti
    Inscrit en
    Février 2011
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 22
    Par défaut
    Merci pour vos réponses Iradrille et Bousk.

    Iradrille, juste une remarque, tu écris :

    Dans tes exemples par contre, il n'y aura pas de copie.
    Dans le premier exemple, dans le main, il n'y a pas une copie de la variable locale 'retour' dans la variable 'a' ?

    Ce que je retiens, après aussi une discussion avec un collègue expérimenté en C++ :
    le passage par référence de la valeur à une fonction qui existe pour retourner cette valeur n'est pas super lisible mais est plus performant : elle évite la création d' objets temporaires dans la fonction.
    Après tout dépend du contexte, c'est un arbitrage à faire entre lisibilité et performance.

Discussions similaires

  1. Fonction qui retourne plusieurs valeurs
    Par maestro982 dans le forum Langage
    Réponses: 3
    Dernier message: 29/09/2011, 14h46
  2. Fonction d'une DLL qui retourne plusieur valeur
    Par vtk37 dans le forum Débuter
    Réponses: 9
    Dernier message: 27/05/2009, 10h01
  3. Fonction qui retourne plusieurs paramètres
    Par diam's dans le forum Langage
    Réponses: 3
    Dernier message: 03/02/2006, 20h11
  4. [PL/SQL] Fonction qui retourne plusieurs valeurs
    Par Loko dans le forum Oracle
    Réponses: 2
    Dernier message: 07/12/2004, 09h43
  5. Réponses: 14
    Dernier message: 09/04/2004, 13h44

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