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 :

Retourner deux valeurs d'une fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 6
    Par défaut Retourner deux valeurs d'une fonction
    Bonjour,

    Actuellement entrain d'apprendre à utiliser les pointeurs, j'essaye un exercice qui consiste à utiliser plusieurs fonctions afin de faire deux opérations élémentaires... une soustraction et une addition...

    Concrètement, le but étant d'avoir une fonction somme ne retournant rien ni aucun affichage avec 3 paramètres (les deux chiffres a additionner et une variable de stockage), une fonction soustraction qui ne retourne rien elle non plus (les deux chiffres a soustraire et une variable de stockage), une fonction calcul qui appelle les deux fonctions précédente avec 4 paramètres (cette fonction n'affiche rien ce n'est pas le but mais doit par contre retourner les deux résultats, celui de la somme et celui de la soustraction).
    Par la suite un simple scanf pour demander deux valeurs et l'appel de la fonction calc(a,b,C,D) afin de réaliser les opérations citées plus haut.

    Pour l'instant j'arrive bien à obtenir le résultat escompté, cependant avec des warnings que je n'arrive pas à régler malgré qu'il soit relativement explicite...
    Auriez vous une idée de la méthode ?
    voici le code en question :

    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 <stdio.h>
     
    int somme(int a,int b, int S){
    	S=a+b;
    }
    int diff(int a,int b,int D) {
    	D=a-b;
    }
    int calc(int a,int b,int* E,int* R) {
     
    	*E=somme(a,b,E);
    	*R=diff(a,b,R);
    }
    int main() {
    	int a=0,b=0,S,D;
    	printf("Entrez la valeur de a et b\n");
    	scanf("%d%d",&a,&b);
     
    	calc(a,b,&S,&D);
    	printf("la somme de a+b = %d, la difference entre a et b est de : %d", S,D);
    }
    Avec pour résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    main.c:3:5: note: expected ‘int’ but argument is of type ‘int *’                                                                                                    
    main.c:12:14: warning: passing argument 3 of ‘diff’ makes integer from pointer without a cast [-Wint-conversion]                                                    
    main.c:6:5: note: expected ‘int’ but argument is of type ‘int *’                                                                                                    
    Entrez la valeur de a et b                                                                                                                                          
    10                                                                                                                                                                  
    15                                                                                                                                                                  
    la somme de a+b = 25, la difference entre a et b est de : -5
    Merci d'avance : )

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    En fait ce qui manque ce sont les warnings signalant d'autres erreurs. Tu devrais activer un niveau de warning plus élevé pour les voir. Si tu ne sais pas comment dis nous quel compilateur tu utilises.
    Les problèmes que je vois :
    - fonction somme(), elle reçoit un S qu'elle n'utilise jamais en lecture (pourquoi le recevoir?)
    - fonction somme(), elle met à jour un paramètre local S alors que ce paramètre va disparaître immédiatement après! Toutes les variables locales sont détruites à la fin d'un bloc, ici ce sont S, b et a. Ici pourtant ce calcul va par la "magie" des registres processeurs rester quelque part.
    - fonction somme(), elle prétend retourner un int, mais il n'y a aucun return. C'est une grave erreur.
    - fonction diff() : les 3 même remarques.
    - fonction calc() : elle passe en 3ième paramètre de somme E qui est l'adresse d'un int. Mais la fonction somme() attendait un simple int. C'est le warning que tu as. Si tu étais en C++ ça serait une erreur grave car c'est très grave.
    - fonction calc() : elle aussi prétend retourner un int mais ne retourne rien.
    - même remarque pour R.
    - fonction main(), là tout est clair, on ne confond pas les intet les pointeurs.

    Maintenant, pourquoi ton code "marche"? C'est en effet un vrai miracle! Au final les bon nombres se retrouvent au endroit, mais c'est une simple coïncidence!

    Maintenant si l'interface de la fonction somme devenait void somme(int a, int b, int* p_s) que deviendraient toutes mes remarques, et quelle corrections seraient nécessaires?

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Skz69 Voir le message
    Actuellement entrain d'apprendre à utiliser les pointeurs, j'essaye un exercice qui consiste à utiliser plusieurs fonctions afin de faire deux opérations élémentaires... une soustraction et une addition...
    Concrètement, le but étant d'avoir une fonction somme ne retournant rien ni aucun affichage avec 3 paramètres (les deux chiffres a additionner et une variable de stockage)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int somme(int a,int b, int S){
    	S=a+b;
    }
    Donc tu es en train d'apprendre les pointeurs. Il est alors fortement probable que ton exercice te demandera d'utiliser des pointeurs. Mais tu ne les utilises pas. Fatalement il y a une incohérence.
    De plus ta fonction "somme()" modifie une variable temporaire ("S") qui sera perdue quand elle se termine. N'as-tu pas appris qu'une fonction ne pouvait en aucun cas modifier le paramètre qu'elle reçoit ? Enfin elle le peut bien entendu mais comme il disparait quand la fonction se termine c'est généralement vide de sens.

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void init(int s) {
        s=123;
    }
     
    int main() {
        int s=500;
        init(s);
        printf("s=%d\n", s);
    }

    Donc si ma fonction init() n'arrive pas à modifier "s", il est peu probable que ta fonction y arrive.

    Par ailleurs tu n'as pas appris à utiliser scanf() (qui, elle, bizarrement, arrive à modifier une variable qu'on lui passe) ?
    Donc réfléchis à ta façon d'appeler scanf() ce qui te permettra de modifier mon exemple pour qu'il puisse modifier "s" ce qui te permettra ensuite de créer ton addition de façon correcte.

    Citation Envoyé par Skz69 Voir le message
    le but étant d'avoir une fonction somme ne retournant rien
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int calc(int a,int b,int* E,int* R) {
     
    	*E=somme(a,b,E);
    	*R=diff(a,b,R);
    }
    Donc si ta fonction somme() ne retourne rien (et c'est son but), pourquoi tu tentes de récupérer ce qu'elle retourne ???

    Citation Envoyé par Skz69 Voir le message
    cette fonction n'affiche rien ce n'est pas le but mais doit par contre retourner les deux résultats, celui de la somme et celui de la soustraction).
    Impossible. En aucun cas une fonction ne peut retourner 2 valeurs en même temps. Et ton code ne reflète pas cet énoncé puisque ta fonction en réalité, ne retourne rien du tout.

    Donc quand ce sera clair dans ta tête sur comment doivent travailler tes différentes fonctions tu auras fait un grand pas en avant...

    Citation Envoyé par dalfab Voir le message
    Maintenant, pourquoi ton code "marche"? C'est en effet un vrai miracle! Au final les bon nombres se retrouvent au endroit, mais c'est une simple coïncidence!
    En fait je pense que la fonction calc() récupère de somme() et diff() les dernières valeurs calculées (stockées dans la pile et récupérées effectivement "par accident"). Ou alors comme les fonctions sont "int" elles retournent quand-même les dernières valeurs. Ou alors c'est cette bizarre syntaxe *S=somme(a, b, S) qui pomme complètement le compilo (quand la tartine tourne deux fois en tombant elle se retrouve quand-même du bon côté).
    C'est évidemment le pire cas qui peut se produire => avoir un code foireux qui produit le bon résultat
    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]

  4. #4
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut Pointeur et fonction
    Bonjour,

    Je pense qu'il est demandé d'écrire une fonction (en fait plutôt une procédure) qui utilise des pointeurs pour retourner des résultats (ie sans return). Peut être quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void SomDif(int a, int b, int *s, int *d) {
    *s = a + b;
    *d = a - b;
    }
    Cependant un passage par référence serait, me semble t-il, plus élégant, mais ce n'est qu'un exercice.

    Salutations

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Je pense qu'il est demandé d'écrire une fonction (en fait plutôt une procédure)
    Contrairement au Pascal, le C ne fait pas de distinction fonction/procédure. D'ailleurs pourquoi Pascal en fait ça...

    Citation Envoyé par Guesset Voir le message
    qui utilise des pointeurs pour retourner des résultats (ie sans return)
    Ca ne veut rien dire "utiliser des pointeurs pour retourner des résultats". La fonction ne retourne rien. Elle remplit des variables prévues pour recevoir les valeurs calculées.

    Citation Envoyé par Guesset Voir le message
    Peut être quelque chose comme :
    T'es pas non plus sensé donner la solution (ie règles du forum)

    Citation Envoyé par Guesset Voir le message
    Cependant un passage par référence serait, me semble t-il, plus élégant, mais ce n'est qu'un exercice.
    Et surtout le passage par références n'existe pas en C.
    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]

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 6
    Par défaut
    Merci pour ces réponses, je vais me pencher sur toutes ces précisions.

    Concernant la solution apporter, c'est à dire que c'est ce que je fais si je ne m'abuse ? et cette solution ne convient pas du fait qu'elle fasse elle même le calcul. Ce n'est pas ce qui est demandé...
    On parle ici d'un exercice qui a 3 fonction :

    1 -> La fonction somme : qui ne retourne rien et qui a 3 paramètres.
    2 -> La fonction différence : qui retourne quelque chose cette fois (D en l’occurrence) et qui a 3 paramètres aussi
    3 -> La fonction calcul, qui utilise ces 2 fonctions pour faire les deux calculs. Cette fonction a 4 paramètres, mais ne fait aucun affichage.
    Enfin dans le main, il est demandé d'utiliser la fonction calcul afin de demander la saisie de deux entiers afin d'appeler la fonction calcul pour effectuer la somme et la différence.

    Je me rends compte que je n'avais pas été clair du tout dans mon premier message.

    Je vais me pencher sur le message de Dalfab, qui semble assez bien résumer la situation.
    Pour ce qui est de mon compilateur j'utilise clang sous débian avec Vi en éditeur...

    Ce que je viens de saisir c'est qu'en aucuns cas je ne dois déclarer mes fonctions somme et calcul en tant que "int" car en soit elle ne retourne rien, je dois donc partir sur une "void", cependant la fonction différence qui elle retourne bien un int est bien déclarer et je peux donc l'appeler dans ma fonction calcul comme ce qui suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void calcul(int a, int b, int* S, int D) {
              D = diff(a,b,D); // correct car diff est de type int et un return D a été rajouté.
    }
    Cependant, il est pas mal difficile selon moi avec le peu de C que j'ai dans les jambe (et le peu de programmation tout simplement, étant en cours du soir sur un cursus m2 tout en étant en activité sur un poste accès réseau qui est d'ailleurs ma formation principale...).

    Ce que je comprends en tout cas, c'est que des pointeurs devront être utilisés entre la fonction somme et calcul ainsi qu'en calcul et le main. Cependant je ne comprends vraiment pas l'intérêt en effet d'avoir une fonction somme avec 3 paramètres alors que S ne sera jamais utilisé...
    C'est un mystère pour moi d'ou ma première version de ce code.

    Je vais me remettre sur ce problème en essayant d'intégrer vos remarques Merci dans tous les cas.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Skz69 Voir le message
    Concernant la solution apporter, c'est à dire que c'est ce que je fais si je ne m'abuse ?
    Pas tout à fait. Guesset fait l'addition directement dans la fonction "SomDif" tandis que toi tu tentes de récupérer l'addition depuis une autre fonction. C'est une nuance.

    Citation Envoyé par Skz69 Voir le message
    et cette solution ne convient pas du fait qu'elle fasse elle même le calcul. Ce n'est pas ce qui est demandé...
    Exact. Mais il a quand-même écrit des trucs intéressant à étudier...

    Citation Envoyé par Skz69 Voir le message
    1 -> La fonction somme : qui ne retourne rien et qui a 3 paramètres.
    Exact
    Citation Envoyé par Skz69 Voir le message
    2 -> La fonction différence : qui retourne quelque chose cette fois (D en l’occurrence) et qui a 3 paramètres aussi
    Citation Envoyé par Skz69 Voir le message
    une fonction soustraction qui ne retourne rien elle non plus
    Ca a donc changé depuis ton premier post !!!

    Citation Envoyé par Skz69 Voir le message
    Je me rends compte que je n'avais pas été clair du tout dans mon premier message.
    Sisi, c'était parfaitement clair.

    Citation Envoyé par Skz69 Voir le message
    Ce que je viens de saisir c'est qu'en aucuns cas je ne dois déclarer mes fonctions somme et calcul en tant que "int" car en soit elle ne retourne rien,
    Totalement exact

    Citation Envoyé par Skz69 Voir le message
    Cependant je ne comprends vraiment pas l'intérêt en effet d'avoir une fonction somme avec 3 paramètres alors que S ne sera jamais utilisé...
    Personne n'a jamais dit que le 3° paramètre ne serait jamais utilisé. Ce que nous avons dit, c'est que toi tu ne l'utilisais pas correctement. Je t'assure que le 3° paramètre sera bel et bien utilisé.
    Et même (petit moment de réflexion), si la fonction somme() reçoit 3 paramètres ; et que les deux premiers sont les entiers devant être additionnés ; et que ton exo traite des pointeurs ; alors il est fortement probable que le 3° paramètre sera un...

    Citation Envoyé par Skz69 Voir le message
    Je vais me remettre sur ce problème en essayant d'intégrer vos remarques
    Concentre-toi sur mon premier exemple: comment modifier init() pour qu'il modifie la variable de l'appelant. C'est la base de tout.
    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]

  8. #8
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut
    bonsoir,

    Citation Envoyé par Sve@r Voir le message
    Contrairement au Pascal, le C ne fait pas de distinction fonction/procédure. D'ailleurs pourquoi Pascal en fait ça...
    Le type void transforme une fonction en procédure même si le terme fonction continue à être utilisé en C. La différence entre fonction et procédure est essentiellement qu'une fonction peut être une RValue ce qui paraît difficile en C si elle est déclarée void.


    Citation Envoyé par Sve@r Voir le message
    Ça ne veut rien dire "utiliser des pointeurs pour retourner des résultats". La fonction ne retourne rien. Elle remplit des variables prévues pour recevoir les valeurs calculées.
    Placer un résultat à une adresse donnée me semble la définition exacte d'un retour de valeurs que ce soit via la pile ou des adresses passées en argument. C'est peut être le terme retourner qui choque en faisant penser à return ?


    Citation Envoyé par Sve@r Voir le message
    T'es pas non plus sensé donner la solution (ie règles du forum)
    Au vu des commentaires qui ont suivi il ne semble pas que ce soit le cas.

    Citation Envoyé par Sve@r Voir le message
    Et surtout le passage par références n'existe pas en C.
    C'est exact, c'est du C++.

    Salutations.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 6
    Par défaut
    Les débats faisant rage, je vois qu'il n'est pas aisé de se mettre d'accord sur ce langage...

    Dans tous les cas pour revenir sur le sujet initial, c'est que je ne comprends pas l'utilité de cet exercice du fait du 3ème argument de la fonction diff et somme je ne vois pas comment et pourquoi l'exploiter avec les éléments que j'ai...
    Car faire :
    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 somme(int a, int b) {
    	int c = a+b;
    	return c;
    }
    int diff(int a, int b) {
    	int d = a - b;
    	return d;
    }
     
    void calcul(int a, int b, int* c, int* d) {
    	*c = somme(a,b);
    	*d = diff(a,b);
     
    }
    int main() {
    	int a=0,b=0,c,d;
    	printf("Entrez la valeur de a et b\n");
    	scanf("%d%d",&a,&b);
     
    	calcul(a,b,&c,&d);
    	printf("la somme de a+b = %d, la difference entre a et b est de : %d", c,d);
    }
    Marche super bien dans ce cas posé, cependant ce qui vient ME poser problème est bien le fait que la fonction somme ne retourne rien (type void sans return) ainsi qu'un 3eme argument sans utilité pour moi (je dis bien pour moi n'ayant pas toutes les cartes pour comprendre cela...) pareil pour la fonction diff qui possède 3 arguments... Pourquoi ? je ne sais pas...

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

Discussions similaires

  1. Impossible de retourner la valeur d'une fonction personnalisée sur Excel
    Par abdelben93 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 10/05/2019, 08h10
  2. comment retourner 2 valeurs avec une fonction
    Par aminebakr dans le forum Langage
    Réponses: 14
    Dernier message: 27/06/2017, 11h58
  3. [XL-2007] Retourner la valeur d'une fonction sur une colonne
    Par renaudjean dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 04/10/2013, 01h27
  4. Pour retourner deux valeurs dans une fonction
    Par IMANE21 dans le forum Débuter
    Réponses: 1
    Dernier message: 03/03/2012, 23h36
  5. Retourner plusieurs valeurs a une fonction ajax
    Par Hyuge dans le forum jQuery
    Réponses: 2
    Dernier message: 11/06/2009, 15h49

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