Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2460 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Retour d'une fonction

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Retour d'une fonction

n°1280541
julien_54
Posté le 10-01-2006 à 15:52:01  profilanswer
 

Bonjour  :hello: ,
 
Je me posais la question suivante :
 
lorsque l'on crée une fonction qui renvoi un résultat structurellement complexe (pointeur sur une structure par exemple...), il y a deux solutions pour renvoyer le résultat :
- soit on passe un parametre par adresse et on y stocke le résultat de la fonction (du coup on peut se garder le retour de la fonction pour y mettre un code d'erreur par exemple)
- soit on renvoi un pointeur sur la structure (créée alors avec de l'allocation dynamique dans le corps de la fonction )
 
Quoi qu'est le mieux et le plus utilisé ?

mood
Publicité
Posté le 10-01-2006 à 15:52:01  profilanswer
 

n°1280546
Elmoricq
Modérateur
Posté le 10-01-2006 à 15:54:50  profilanswer
 

Si ma fonction ne retourne pas d'autre information qu'une structure (ou NULL si erreur), je retourne la structure directement.
Ca évite de faire mumuse avec des pointeurs de pointeurs de pointeurs de ...
 
Si je dois renvoyer plusieurs informations, en plus de savoir si ça s'est bien passé ou non (par exemple un nombre de structures créées ou autre), je passe par adresse.
 
Après, j'imagine que chacun sa manière de faire. [:spamafote]

n°1280573
julien_54
Posté le 10-01-2006 à 16:17:09  profilanswer
 

J'aurais pensé qu'il existait une sorte de convention ...  
Genre strcpy demande bien un pointeur pour le résultat (j'imagine que c pour laisser à l'utilisateur le soin de gérer la mémoire) alors qu'il pourrait très bien retourner une copie directement ...
Je pense qu'il doit y avoir aussi une histoire de : si création d'un nouvel objet alors retour direct sinon passage de l'objet en parametre par adresse...
 
en tout cas merci de ta réponse (c'est aussi un peu comme cela que je pense le truc, mais comme je voudrais encore m'améliorer je cherche la petite bête ;)

n°1280576
ritzle
Posté le 10-01-2006 à 16:19:32  profilanswer
 

julien_54 a écrit :


Genre strcpy demande bien un pointeur pour le résultat (j'imagine que c pour laisser à l'utilisateur le soin de gérer la mémoire) alors qu'il pourrait très bien retourner une copie directement ...


ben les string sont deja des pointeurs, alors...

n°1280586
Elmoricq
Modérateur
Posté le 10-01-2006 à 16:26:38  profilanswer
 

julien_54 a écrit :

J'aurais pensé qu'il existait une sorte de convention ...  
Genre strcpy demande bien un pointeur pour le résultat (j'imagine que c pour laisser à l'utilisateur le soin de gérer la mémoire) alors qu'il pourrait très bien retourner une copie directement ...


 
strcpy() ne crée rien, il écrit dans une zone mémoire ; dans ma réponse je suis parti du principe que je créais la structure, parce que dans les autres cas de figure, la question ne se pose pas.
Même s'il y a de (bien petites) subtilités, comme dans le cas de fgets() par exemple.
 

julien_54 a écrit :

Je pense qu'il doit y avoir aussi une histoire de : si création d'un nouvel objet alors retour direct sinon passage de l'objet en parametre par adresse...


 
Ca dépend de ce que tu dois retourner. Un passage par adresse ne sert que rarement à la création d'un nouvel objet, je ne trouve cela justifié que si plusieurs données doivent être retournées. Et encore, y a souvent un problème de conception derrière (parce que ça suppose de passer en paramètre une variable non encore définie, ou nulle, moi ça me pose un problème).
Le passage par adresse sert surtout à modifier la valeur d'une variable déjà créée. Comme dans le cas de strcpy(), justement.


Message édité par Elmoricq le 10-01-2006 à 16:36:03
n°1280641
julien_54
Posté le 10-01-2006 à 16:50:26  profilanswer
 

D'accord avec toi si ce n'est le fait que pour strcpy le passage par adresse ne se justifie pas par "modifier la valeur d'une variable déjà créée" puisque justement à part "écrire dans une zone mémoire", strcpy ne modifie rien (en terme de valeur, pas en terme de mémoire) au mieux il écrase, contrairement à strcat qui a bien comme objectif de modifier la valeur ...

n°1280648
Elmoricq
Modérateur
Posté le 10-01-2006 à 16:52:59  profilanswer
 

[:pingouino]
 
Dans le fond, aucune différence entre strcpy() et strcat().  
Le premier écrit depuis le début, le second écrit à partir du premier caractère NULL qu'il trouve.
Point barre.

Message cité 1 fois
Message édité par Elmoricq le 10-01-2006 à 16:53:39
n°1280668
julien_54
Posté le 10-01-2006 à 17:05:46  profilanswer
 

Pas au niveau conceptuel (l'un crée l'autre modifie...)
En tout cas ce n'est pas le sujet de mon post...  
N'y a t'il pas un avantage d'optimisation au niveau du retour de fonction avec parametre par adresse ...?

n°1280681
Elmoricq
Modérateur
Posté le 10-01-2006 à 17:10:45  profilanswer
 

julien_54 a écrit :

Pas au niveau conceptuel (l'un crée l'autre modifie...)
En tout cas ce n'est pas le sujet de mon post...


 
Non. Le concept est le même, c'est une écriture dans une zone mémoire préalablement allouée.
L'écriture ne débute pas au même endroit, c'est tout.
Si tu veux deux concepts différents, étudie strdup() et strcpy().
 

julien_54 a écrit :

N'y a t'il pas un avantage d'optimisation au niveau du retour de fonction avec parametre par adresse ...?


 
Optimisation n°1 : ne pas optimiser.
 
Surtout à ce niveau-là. Les optimisations de taille se situent au niveau des algorithmes employés.
Si tu as besoin faire de la micro-optimisation, tu as de sérieux ennuis.

n°1280708
julien_54
Posté le 10-01-2006 à 17:22:13  profilanswer
 

Lorsque l'on manipule des programmes dont la partie critique recouvre 50 % du temps de l'execution et que cette partie est un algorithme mathématique déjà connues et reconnues par des mathématiciens experts, on peut avoir à optimiser, voir utiliser des routines d'appel de code assembleur directement dans le code C.  
 
Mais encore une fois ce n'est pas le sujet, je cherche juste des idées fraiches et judicieuses provenant d'expériences riches d'autres programmeurs, pour mettre à jour mes connaissances...

mood
Publicité
Posté le 10-01-2006 à 17:22:13  profilanswer
 

n°1280828
matafan
Posté le 10-01-2006 à 19:18:00  profilanswer
 

On fait comme on veut, suivant les cas.
 
Il y a des cas ou tu es oblige de passer un parametre par reference, plutot que d'utiliser la valeur de retour : par exemple si la fonction doit retourner plusieurs structures (car on ne peut evidemment retourner qu'une seule valeur), ou si tu preferes utiliser la valeur de retour pour indiquer differents cas d'erreur (bref au lieux d'avoir simplement NULL <=> erreur, tu consideres que 1 indique un type d'erreur, 2 un autre type d'erreur...). Apres, a partir du moment ou dans une API tu as un cas ou tu a besoin de passer par reference, il peut etre judicieux, par souci de consistence, d'utiliser systematiquement des references plutot que les valeurs de retour.
 
Je ne vois pas en quoi passer par la valeur de retour serait plus rapide que passer par une reference.
 
Si on peut passer par la valeur de retour, alors on peut aussi passer par une reference. Le contraire n'est pas vrai. La solution par reference est donc plus generale est plus soupe.
 
Ca ne veut pas dire pour autant qu'il faut systematiquement passer par une reference. Il y a des cas ou utiliser la valeur de retour peut sembler plus "naturel". Ca peut etre le cas par exemple si ta fonction a principalement un role de "constructeur", comme strdup par exemple. Il peut sembler plus naturel de faire c = new_circle(center, radius) que new_circle(&c, center, radius) car l'output (c) est clairement separe de l'input (center et radius).

n°1280873
Elmoricq
Modérateur
Posté le 10-01-2006 à 20:11:09  profilanswer
 

julien_54 a écrit :

Lorsque l'on manipule des programmes dont la partie critique recouvre 50 % du temps de l'execution et que cette partie est un algorithme mathématique déjà connues et reconnues par des mathématiciens experts, on peut avoir à optimiser, voir utiliser des routines d'appel de code assembleur directement dans le code C.  
 
Mais encore une fois ce n'est pas le sujet, je cherche juste des idées fraiches et judicieuses provenant d'expériences riches d'autres programmeurs, pour mettre à jour mes connaissances...


 
Idée à exploiter : plutôt que de micro-optimiser, ce qui en dehors de cas très précis ne sert pas à grand chose d'autre qu'à rendre le code difficilement compréhensible, il vaut mieux utiliser un logiciel de profiling.
A partir de ça on peut déterminer quelle partie du programme est la plus consommatrice, et pourquoi. On peut très facilement améliorer les performances sans circonvenir à la lisibilité du code avec ce type d'outil.

n°1281037
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-01-2006 à 00:06:20  profilanswer
 

Elmoricq a écrit :

à partir du premier caractère NULL qu'il trouve.


nul ou null !


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1281063
Sve@r
Posté le 11-01-2006 à 01:50:42  profilanswer
 

julien_54 a écrit :

Lorsque l'on manipule des programmes dont la partie critique recouvre 50 % du temps de l'execution et que cette partie est un algorithme mathématique déjà connues et reconnues par des mathématiciens experts, on peut avoir à optimiser, voir utiliser des routines d'appel de code assembleur directement dans le code C.  
 
Mais encore une fois ce n'est pas le sujet, je cherche juste des idées fraiches et judicieuses provenant d'expériences riches d'autres programmeurs, pour mettre à jour mes connaissances...


 
Dans le cas où tu passes à ta fonction l'adresse d'un objet existant, tu dois d'abord t'assurer que l'objet existe bien avant d'appeler la fonction. C'est le cas de "strcpy()"
 
Dans le cas où ta fonction renvoie un pointeur sur un objet qu'elle aura créé elle-même, tu t'affranchis de ta préoccupation de création mais tu es obligé de t'assurer toi-même de la libération de la mémoire allouée. C'est le cas de "strdup()" (merci Elmoricq pour ces exemples bien choisis)
 
Chaque solution a donc ses avantages et ses inconvénients. Personnellement (je sais pas pourqoui) je préfère la première solution. Peut-être parce que j'associe inconsciemment "free" avec "malloc" et que j'aime pas l'utiliser si j'ai pas fait moi-même le malloc...
Par ailleurs, je trouve que c'est plus facile de porter une fonction de ce style en C++.
 
Exemple en C

struct s_travail {
    <tititi>
    <tatata>
    <tututu>
};
 
void Action(struct s_travail *pt, ..., ...)
{
    pt-><tititi>=...
    pt-><tatata>=...
    pt-><tututu>=...
}


 
Le même en C++

class c_travail {
    public:
    <tititi>
    <tatata>
    <tututu>
    void Action(..., ...);
};
 
void c_travail::Action(..., ...)
{
    this-><tititi>=...
    this-><tatata>=...
    this-><tututu>=...
    // Et encore, le mot "this" peut être omis...
}

Message cité 1 fois
Message édité par Sve@r le 11-01-2006 à 01:54:09

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1281099
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-01-2006 à 08:38:51  profilanswer
 

Sve@r a écrit :

Chaque solution a donc ses avantages et ses inconvénients. Personnellement (je sais pas pourqoui) je préfère la première solution. Peut-être parce que j'associe inconsciemment "free" avec "malloc" et que j'aime pas l'utiliser si j'ai pas fait moi-même le malloc...


C'est pour ça que je préfère implémenter clairement des 'constructeurs/destructeurs' (xxx_create() / xxx_delete()) :


   xxx_s *p = xxx_create();
 
   if (p != NULL)
   {
      xxx_usage (p, ...);
 
      xxx_delete(p), p = NULL;
   }


http://mapage.noos.fr/emdel/tad.htm


Message édité par Emmanuel Delahaye le 11-01-2006 à 08:41:27

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1281100
julien_54
Posté le 11-01-2006 à 08:40:26  profilanswer
 

Merci pour tous les messages constructifs !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Retour d'une fonction

 

Sujets relatifs
Peut ont recupére la valeur de retour d'une fonction JS dans du php?[delphi]Retour de fonction - Type incompatible
Retour d'une fonction [DEBUTANT]passage de parametres a 1 fonction pb de retour
retour erreur de la fonction php mail()try/catch et retour de fonction
Valeur de retour d'une fonction si erreurbesoin de testeurs: retour de fonction
[Python] Threads : retour de la fonction executée par un thread[C] pointeurs de pointeurs en retour de fonction...
Plus de sujets relatifs à : Retour d'une fonction


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR