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 :

Renvoi de plusieurs valeurs avec une fonction


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut Renvoi de plusieurs valeurs avec une fonction
    Bonjour,

    Dans un programme que je fais actuellement, je fais appel à une fonction. Celle-ci doit renvoyer deux valeurs.

    Etant donné qu'une fonction ne peut renvoyer qu'un seul élément, j'ai essayé d'utiliser un tableau dans lequel je stocke mes deux valeurs. Mais lors de la compilation, il me fait comprendre qu'il n'aime pas ce que je fais...

    Faut-il utiliser un pointeur? Sinon comment peut-on renvoyer plusieurs valeurs dans un main avec une seule fonction?

    Merci

  2. #2
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 168
    Points : 110
    Points
    110
    Par défaut
    Citation Envoyé par Dub's
    Bonjour,

    Dans un programme que je fais actuellement, je fais appel à une fonction. Celle-ci doit renvoyer deux valeurs.

    Etant donné qu'une fonction ne peut renvoyer qu'un seul élément, j'ai essayé d'utiliser un tableau dans lequel je stocke mes deux valeurs. Mais lors de la compilation, il me fait comprendre qu'il n'aime pas ce que je fais...

    Faut-il utiliser un pointeur? Sinon comment peut-on renvoyer plusieurs valeurs dans un main avec une seule fonction?

    Merci
    Salam,

    il y a plusieurs méthodes, voila un petit 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    include <stdio.h>
     
    int * manyValue ()
    {
      int *tableau;
      tableau = (int*)malloc(2);
      tableau [0] = 0;
      tableau [1] = 1;
      return (tableau);
    }
     
     
    void main(void)
    {
       int *tableauTemp; 
     
       clrscr();
     
       tableauTemp = manyValue();
     
       printf ("tableauTemp [0] = %d",tableauTemp[0]);
       printf ("\ntableauTemp [1] = %d",tableauTemp[1]);
     
       getchar();
     
    }
    cdt,

    turbo_chess

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Dub's
    Dans un programme que je fais actuellement, je fais appel à une fonction. Celle-ci doit renvoyer deux valeurs.
    Si ce sont 2 valeurs 'simples' comme 2 int ou 2 long, on peut retourner une structure
    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
     
    struct data
    {
       int a;
       int b;
    };
     
    struct data f(...)
    {
       struct data x;
       x.a = 123;
       x.b = 456;
     
       return x;
    }
     
    {
       struct data xx;
     
       xx = f(...);
     
    }
    C'est ce que font div(), ldiv()...

    Mais c'est pour des cas simples avec peu de valeurs, car il y a des copies...

    Le cas général, c'est la structure de sortie dont on passe l'adresse.
    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
    struct data
    {
       int a;
       int b;
    };
     
    void f (..., struct data *p_out)
    {
       p_out->a = 123;
       p_out->b = 456;
    }
     
    {
       struct data xx;
     
       f (..., &xx);
     
    }
    Rien qu'a la lecture, on voit bien que le code est beaucoup plus simple. En fait, il est même beaucoup plus efficace, car il n'y a qu'une copie (une adresse, quelque soit la taille de la structure). Ensuite, l'écriture du résultat se fait directement pendant l'exécution de la fonction

    Attention cependant aux effets indésirables possibles si un autre thread utilise les même données. une synchronisation peut être nécessaire.

  4. #4
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Dub's
    Etant donné qu'une fonction ne peut renvoyer qu'un seul élément,
    tu veux dire retourner , n'est-ce pas ?


    Citation Envoyé par Dub's
    Faut-il utiliser un pointeur ?
    La réponse est OUI, si tu modifies ou affecte ces valeurs dans la fonction.

    Citation Envoyé par Dub's
    Sinon comment peut-on renvoyer plusieurs valeurs dans un main avec une seule fonction?
    Pourquoi dans un main ????


    Pour répondre simplement, c'est dans tout livre de C...

    En gros

    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
     
    #include <stdlib.h>
    #include <stdio.h>
     
    void fonction ( int *param1, int *param2 )
    {
        *param1 = 0 ;
        *param2 = 1 ;
    }
     
    int main ( void )
    {
        int i1 ;
        int i2 ;
        int s ;
     
        fonction ( &i1, &i2 );
        printf ( "Parametre 1 : %d parametre 2 : %d",i1,i2);
     
        return 0 ;
    }

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par turbo_chess
    #include <stdio.h>


    int * manyValue ()
    Pas de paramètres : void
    {
    int *tableau;
    tableau = (int*)malloc(2);
    inutilement complexe. Manque le test d'echec d'allocation. Manque <stdlib.h>
    tableau [0] = 0;
    tableau [1] = 1;
    return (tableau);
    }
    Parenthèses inutile (return n'est pas une fonction).

    void main(void)
    main() retourne int. Toujours.

    {
    int *tableauTemp;

    clrscr();
    Fonction inconnue. Pas de prototype déclaré.

    tableauTemp = manyValue();
    pas de tests d'echec...
    printf ("tableauTemp [0] = %d",tableauTemp[0]);
    printf ("\ntableauTemp [1] = %d",tableauTemp[1]);
    Curieuse façon de placer le \n. Le "caractère de fin de ligne", c'est en ... fin de ligne, non ?
    getchar();
    Inutile

    Comme main() retourne un int, ajouter
    return 0;
    }
    Conception douteuse. Sortir un malloc pour 2 valeurs est exagéré. De plus, il faut penser à libérer ce qui a été alloué, ce qui, quelle surprise !, a été oublié ici...

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        fonction ( &i1, &i2 );
    Pourquoi copier 2 adresses quand on peut n'en copier qu'une avec une structure...

  7. #7
    Membre régulier
    Inscrit en
    Juillet 2002
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 168
    Points : 110
    Points
    110
    Par défaut
    Bonjour,

    merci Emmanuel pour les corrections.

    en effet à l'aide d'une strcuture c'est plus facile.

    turbo_chess

  8. #8
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Pourquoi copier 2 adresses quand on peut n'en copier qu'une avec une structure...
    bah c'était pour répondre à sa question "comment retourner plusieurs valeurs"....

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34
    bah c'était pour répondre à sa question "comment retourner plusieurs valeurs"....
    Il n'a pas, et c'est logique, parlé de la manière de le faire...

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par turbo_chess
    en effet à l'aide d'une strcuture c'est plus facile.
    facile ? Pour qui ? Le programmeur, l'utilisateur ?

    Ce qui compte c'est (ordre indifférent):
    • la simplicité d'implémentation
    • la facilité d'utilisation
    • l'efficacité
    • la robustesse

  11. #11
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    voilà...

    En fait c'était pour ça que j'avais cité ce cas...

    Peu de paramètres : plus clair et facile chaque paramètre par adresse (un peu overkill une structure pour 2 paramètres)
    Beaucoup de paramètres : stucture

  12. #12
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par turbo_chess
    int * manyValue ()
    {
    int *tableau;
    tableau = (int*)malloc(2);
    tableau [0] = 0;
    tableau [1] = 1;
    return (tableau);
    }
    Attention, ton malloc alloue 2 octets et non pas 2 int.
    Il faudrait écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      int *tableau;
      tableau = malloc(2*sizeof *tableau);

  13. #13
    Futur Membre du Club
    Inscrit en
    Mars 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut problème avec p_out->a = 123;
    J'ai utilisé une structure, mais je rencontre un problème lors de la saisie de cette ligne:

    p_out->a = 123;

    Je vois bien que "a" fait référence à l'élément dans le struct, mais il m'indique un message d'erreur lors de la compilation:

    error: dereferencing pointer to incomplete type

    Pourtant, dans mon cas concret, j'ai déclaré mes variables. Je ne comprends ce que signifie cette erreur.

  14. #14
    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
    C'est généralement qu'à ce moment-là, le compilo sait que p_out est un pointeur vers une structure, mais il n'a pas "vu" la définition de la structure : Il ne sait donc ni la taille de la structure, ni quels sont ses champs...

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Dub's
    J'ai utilisé une structure, mais je rencontre un problème lors de la saisie de cette ligne:

    p_out->a = 123;

    Je vois bien que "a" fait référence à l'élément dans le struct, mais il m'indique un message d'erreur lors de la compilation:

    error: dereferencing pointer to incomplete type

    Pourtant, dans mon cas concret, j'ai déclaré mes variables. Je ne comprends ce que signifie cette erreur.
    Ca signifie que la définition complète de la structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct data
    {
       int a;
       int b;
    };
    n'est pas visible.

    Si le code est répartit dans des fichiers différents, cette définition va dans le même header (.h) que celui des prototypes des fonctions qui l'utilise.

    Montre ton code.

Discussions similaires

  1. Renvoyer plusieurs valeurs avec une fonction
    Par Kestion100 dans le forum Excel
    Réponses: 4
    Dernier message: 10/12/2014, 11h56
  2. Réponses: 3
    Dernier message: 13/11/2008, 09h21
  3. Réponses: 1
    Dernier message: 16/03/2007, 17h30
  4. Réponses: 6
    Dernier message: 10/01/2007, 13h16
  5. Retourner une valeur avec une fonction
    Par stephtbest dans le forum ASP
    Réponses: 4
    Dernier message: 31/10/2003, 16h37

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