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 :

[Débutant] Valeur de retour de fonction ou pointeur en parametre


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 2
    Points
    2
    Par défaut [Débutant] Valeur de retour de fonction ou pointeur en parametre
    Bonjour,

    en suivant quelques tuto je suis tombé sur un cas pratique qui consiste à écrire un convertisseur de degrés (fahrenheit->Celsisus) à l'aide d'un fonction stockée dans un fichier source indépendant. Je l'ai résolu de la sorte :

    La fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    float farhenheitToCelsius(float fFahr){
    	return (5.0f/9.0f)*(fFahr-32.0f);
    }
    Son utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int main() {
    	float fCelcius;
    	float fFahrenheit = 100.0f;
     
    	fCelcius = farhenheitToCelsius(fFahrenheit);
     
    	printf("%f F = %f C", fFahrenheit, fCelcius);
    }
    Tout fonctionne pas de problèmes. En revanche la "correction" utilise une fonction de cette forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int farhenheitToCelsius(float fFahr, float *fCel){
    	*fCel = (5.0f/9.0f)*(fFahr-32.0f);
    	return 0;
    }
    et l'utilise ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int main(int argc, char *argv[]) {
    	float fCelcius;
    	float fFahrenheit = 100.0f;
     
    	farhenheitToCelsius(fFahrenheit, &fCelcius);
     
    	printf("%f F = %f C", fFahrenheit, fCelcius);
    }
    D'où ma question, pourquoi ne pas utiliser la valeur de retour de la fonction ? Y a t il un intérêt évident à utiliser un pointeur en paramètre pour la valeur de retour qui m'a échappé ? Y a t il des limites de quelques sortes que ce soit avec les valeur de retour de fonction ?

  2. #2
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Certainnement que le programmeur utilise une méthode de programmation qui réserve les retours de fonction pour les codes d'erreur (0 == tout va bien).

    C'est souvent une technique qu'on retrouve dans les anciennes bibliothèques écrites en C.

    Aujourd'hui on peut lever des exceptions si vraiment un problème survient, donc la méthode est un peu désuette si les erreurs possibles ne sont pas dans le flot de traitement de l'application et dans ton cas, totalement inutile. Je préfère de loin ta version.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Pas de contre-indications pour la valeur de retour donc. Merci pour la réponse.

  4. #4
    Membre du Club
    Inscrit en
    Août 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Août 2006
    Messages : 36
    Points : 50
    Points
    50
    Par défaut
    C'est un peu dommage de designer une fonction si simple comme ça. Le code de retour dans ce cas très précis n'a pour moi d'intérêt que si on peut te rentrer des ranges de valeurs de paramètres abbérantes.

    Par contre ce type de fonction avec signature void permet d'éviter une création d'object temporaire, celui de ta valeur de retour, en stockant directement la réponse dans l'espace mémoire dans lequel tu vas la ranger par la suite.
    Mais tu gagnes peu pour des valeurs de base comme des int pour un confort d'utilisation franchement plus chiant.

    De plus, tu prends le risque de rendre ta fonction plus dure à comprendre pour quelqu'un qui voudra la réutiliser, surtout si la doc laisse à désirer.

  5. #5
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Par contre ce type de fonction avec signature void permet d'éviter une création d'object temporaire, celui de ta valeur de retour, en stockant directement la réponse dans l'espace mémoire dans lequel tu vas la ranger par la suite.
    Ca revient au même, si tu passes un pointeur en parametre, il faut bien copier l'adresse car elle est passée par valeur... donc sur un type primitif tu ne gagnes rien.

    Par contre, si tu mets ta fonction inline, là tu pourras espérer des gains de perfs si tu renvoies le résultat, car il n'y aura pas de temporaire.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    si j'ai bien compris ça peut être intéressant, d'un point de vu performance, si la valeur de retour est plus complexe qu'un simple type primitif : une copie d'adresse contre un création et une copie d'objet plus complexe.

    Et pour une fonction simple, la déclarer inline améliore aussi les choses.

    Merci pour toutes ces précisions.

  7. #7
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par yolpo
    Si j'ai bien compris ça peut être intéressant, d'un point de vu performance, si la valeur de retour est plus complexe qu'un simple type primitif : une copie d'adresse contre un création et une copie d'objet plus complexe.

    Et pour une fonction simple, la déclarer inline améliore aussi les choses.

    Merci pour toutes ces précisions.
    Oui mais pas tout à fait.

    Pour une fonction inline qui renvoie un type complexe, il n'y aura pas non plus de copie de l'objet renvoyé (on rappelle que l'appel à une fonction inline est remplacé directement par tout le code contenu dans la fonction, un peu à la manière d'une macro, mais avec plus de sécurité).

    Donc les fonctions inline dans le principe, c'est toujours bien. En pratique il faut faire attention car si ta fonction inline fait elle même appel à d'autres fonctions inline, qui font appel... et si ta fonction est appellée à beaucoup d'endroits, alors il y aura beaucoup de duplication de code dans le binaire généré qui risque de devenir vite volumineux.

    L'inlining n'est pas non plus compatible avec le polymorphisme dynamique. (inline virtual == pas correct)

    Par contre tu peux utiliser l'inlining pour des fonctions membres de classe sans problème.

    Je ne sais pas si c'est possible avec les fonctions statiques, à priori je ne vois pas de contre logique.


    En général, le fait de passer plusieurs références non constantes (ou pointeurs) pour pallier le fait qu'il n'y ait qu'un objet retourné montre (parfois) que ta fonction fait trop de choses, est mal découpée.

    Il arrive tout de même que l'on y soit forcé mais voir à chaque fonction ce genre de chose montre qu'il y a un problème.

    En espérant t'avoir éclairer, bonne prog !

    Si d'autres veulent me compléter ou me corriger.

  8. #8
    Membre du Club
    Inscrit en
    Août 2006
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Août 2006
    Messages : 36
    Points : 50
    Points
    50
    Par défaut
    Tout à fait pour la création de référence qui est de même taille qu'un type de base

    Pour le design de fonctions comme celle dont parle ton post, je conseille le découpage en fonctionalités simple et faciles à comprendre. Comme dit plus haut, si ta fonction modifie plusieurs objets, poses-toi la question du pourquoi fait-elle plusieurs actions? ne serait-ce pas mieux de décomposer en plusieurs fonctions ne faisant que ce que laisse présager leur nom? Tu améliorera la maintenabilité, la réutilisabilité et la lisibilité de ton travail.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    J'ai encore un bout de chemin à parcourir avant de penser "optimisation". Ceci dit je garde tout ça dans un coin de ma tête, en particulier les remarques sur les fonctions usine-à-gaz-qui-font-trop-de-trucs.

    Merci encore

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

Discussions similaires

  1. Valeur de retour pour fonction
    Par oufou dans le forum Débuter
    Réponses: 7
    Dernier message: 19/09/2014, 16h02
  2. Réponses: 3
    Dernier message: 27/02/2012, 17h52
  3. DEBUGGING et valeur de retour de fonction - Comment faites-vous ?
    Par arketip dans le forum Général Python
    Réponses: 13
    Dernier message: 08/11/2009, 13h23
  4. Réponses: 11
    Dernier message: 25/03/2008, 23h12
  5. Pourquoi une seule valeur de retour pour les fonctions ?
    Par Bruno75 dans le forum Langages de programmation
    Réponses: 33
    Dernier message: 18/01/2004, 13h58

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