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

 


Dernière réponse
Sujet : [C] une fonction qui renvoie un tableau de 3 doubles ??
verdy_p

la viper a écrit a écrit :

euh ouhai mais là c'est loin d'être important ! ...  
un tableau de 3 doubles ... tout est fixé et le prog tient en 3 ligne .. basta .




Ce n'est pas une question de principe:
en fait tout dépend de la durée de vie des trois variables retournées. Mais à priori, une fonction qui ne retourne que 3 valeurs devrait se passer d'allouer de la mémoire: c'est à l'appelant d'allouer la mémoire si nécessaire, et seulement si ces données s'inscrivent dans une structure plus complexe dont la durée de vie dépasse la fonction ou si il y a de nombreuses cellules (à priori en nombre indéterminé) à manipuler dans la fonction appelante... Sinon effectivement, l'appelant a tout intérer à allouer ces variables dans la pile en les déclarant localement (variables auto)


Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
verdy_p

la viper a écrit a écrit :

euh ouhai mais là c'est loin d'être important ! ...  
un tableau de 3 doubles ... tout est fixé et le prog tient en 3 ligne .. basta .




Ce n'est pas une question de principe:
en fait tout dépend de la durée de vie des trois variables retournées. Mais à priori, une fonction qui ne retourne que 3 valeurs devrait se passer d'allouer de la mémoire: c'est à l'appelant d'allouer la mémoire si nécessaire, et seulement si ces données s'inscrivent dans une structure plus complexe dont la durée de vie dépasse la fonction ou si il y a de nombreuses cellules (à priori en nombre indéterminé) à manipuler dans la fonction appelante... Sinon effectivement, l'appelant a tout intérer à allouer ces variables dans la pile en les déclarant localement (variables auto)

la viper euh ouhai mais là c'est loin d'être important ! ...  
un tableau de 3 doubles ... tout est fixé et le prog tient en 3 ligne .. basta .
verdoux Euh 95% des données d'un programme sont en mémoire dynamique, dès que le programme devient un peu important.
la viper comment reinventer le monde à partir d'une fonction bete ?
 
faut aller au plus simple ! on a jamais dit qu'on devait passer par de la gestion de memoire dynamique ... tant qu'on y est autant refaire le compilateur et windows dans la même foulée !!
verdy_p En C ANSI tu peut aussi passer une référence de structure:
struct t {
double  tab[3]; /* ou double x,y,z; */
};
 
/* Version où le tableau retourné est passé en paramètre */
function f(struct t &t) {
  t.tab[0] = ...; /* ou t.x = ... */
  t.tab[1] = ...; /* ou t.y = ... */
  t.tab[2] = ...; /* ou t.z = ... */
}
main() {
  struct t ret;
  f(ret);
  printf("%lf %lf %lf", ret.tab[0], ret.tab[1], ret.tab[2]);
/* ou printf("%lf %lf %lf", ret.x, ret.y, ret.z); */
}
 
/* Version en passant 3 références aux variables à retourner */
function f (double &x, double &y, double &z) {
  x = ...;
  y = ...;
  z = ...;
}
main() {
  double x, y, z;
  f(x, y, z);
  printf("%lf %lf %lf", x, y, z);
}
 
Tu peux aussi utiliser directement une déclaration de tableau:
 
f(double tab[3]) {
  tab[0] = ...;
  tab[1] = ...;
  tab[2] = ...;
}
main() {
  double ret[3];
  f(ret);
  printf("%lf %lf %lf", ret[0], ret[1], ret[2]);
}
 
Maintenant si on suppose que le tableau n'est pas déclaré par l'appelant et n'est pas passé en paramètre, mais retourné à l'appelant, la seule façon est de l'allouer dynamiquement dans f:
 
double[3] f() {
  double tab[] = (double[])calloc(sizeof double, 3);
/* et aussi, en C++ seulement: double tab[] = new double[3]; */
  tab[0]=...;
  tab[1]=...;
  tab[2]=...;
  return tab;
}
main() {
  double ret[];
  ret = f();
  printf("%lf %lf %lf", ret[0], ret[1], ret[2]);
  free((void*)ret); /* en C++: delete[] ret; */
}
 
/* version avec un typedef de tableau */
typedef double tableau[3];
tableau *f() {
  tableau *tab = (tableau *)malloc(sizeof tableau);
  /* et aussi, en C++ seulement: tableau *tab = new tableau; */
  (*tab)[0] = ...;
  (*tab)[1] = ...;
  (*tab)[2] = ...;
  return tab;
}
main() {
  tableau *ret;
  ret = f();
  printf("%lf %lf %lf", (*ret)[0], (*ret)[1], (*ret)[2]);
  free((void*)ret); /* en C++: delete ret; */
}
 
/* version avec une structure ou classe C++ */
typedef struct t {
  double tab[3]; /* ou double x,y,z; */
} tableau;
tableau *f() {
  tableau *val;
  val = (tableau*)calloc(sizeof tableau);
  /* et aussi, en C++ seulement: tab = new tableau;
  val->tab[0] = ...; /* ou tab->x = ...; */
  val->tab[1] = ...; /* ou tab->y = ...; */
  val->tab[2] = ...; /* ou tab->z = ...; */
  return val;
}
main() {
  tableau *ret;
  ret = f();
  printf("%lf %lf %lf", ret->tab[0], ret->tab[1], ret->tab[2]);
/* ou printf("%lf %lf %lf", ret->x, ret->y, ret->z); */
  free((void*)ret); /* ou en C++: delete ret; */
}
 
Le principal ennui avec les versions dynamiques où la fonction alloue la place pour le résultat est qu'elle confie la désallocation à l'appelant, et que cela peut générer non seulement des lenteurs (trop de new ou de malloc ou calloc), mais en plus il est plus difficile de maintenir le programme car des oublis de désallocation ou le problème des désallocations différées ou des références multiples à gérer pour savoir quand on peut libérer l'objet peuvent survenir.
Dans ce cas, il vaut mieux conceptuellement considérer que la fonction agit tel un constructeur C++, et qu'à tout constructeur (appel de f() dans un contexte local de variables ou scope) doit être associé un destructeur dans le même scope.
Aussi les solutions où c'est l'appelant qui s'occupe de gérer l'allocation de la valeur de retour d'une fonction sont en général plus propres (c'est le même cas ici quand une fonction doit retourner une chaine de caractères, qui est aussi un tableau de caractères): l'appelant précise à la fonction l'adresse ou la référence de la structure ou du tableau à retourné complété, accompagné d'indication telle que la longueur maximale du tableau, pour que la fonction adopte un comportement approprié en cas d'insuffisance de taille, par exemple retourner au programme client une indication d'erreur.

 

[edit]--Message édité par verdy_p--[/edit]

la viper passage de variables :
3 doubles -> 3*4 = 12 octets
 
passage de pointeurs :
4 octets
 
en admettant que ton tableau n'est pas dynamique et que son adresse ne change pas.
 
void fct(double* tab,int angle)
{
   for(int i=0;i<3;i++)
     tab[i] += angle;
}
 
ca fonctionne ca prend que 4 octets en parametre.
 
double* fct(double* tab,int angle) -> aucun interet car la fonction renvoie exactmeent la meme adresse que celle qui est entrée en paramettre .. puisque l'adresse du tableau ne change pas.
LeGreg Si tu programmes en C, la deuxieme version devient:
 
coord fonction (const coord *mescoord, int angle) {
  coord mesnouvellescoord;
  mesnouvellescoord.x = f(mescoord->x, mescoord->y, mescoord->z);  
  ...
  return mesnouvellescoord;  
}  
 
Legreg
LeGreg typedef struct {
 double x,y,z;
} coord;
 
coord fonction (coord mescoord, int angle) {
 ..
 return mesnouvellescoord;
}
 
Ca marche pas ca?
Ou encore en C++:
 
coord fonction (const coord &mescoord, int angle) {
 ..
 return mesnouvellescoord;
}
 
Sinon la solution du pointeur ca marche aussi
meme si parfois on voudrait etre sur d'obtenir
un nouvel objet et pas modifier les donnees sur place.
(ca depend ce que tu veux)
 
Legreg
korben Salut
Je te rappelle que tu ne peux pas passer des tableaux mais des pointeurs.
 
Tu dois donc passer un pointeur(ou référence) sur ton tableau. Pas d'autre solution, surtout si tu veux le resortir.
 
Si tu as d'autres questions, mail-moi.
@+
janoscoder il faut faire par exemple
void func(double * mod, double angle)
{
 mod[0]=cos(angle);
 mod[1]=sin(angle);
 mod[2]=tan(angle);
}
bemixam je veux faire une fonction qui prend en parametre un tableau de 3 doubles
 
double coord[3]
 
j aimerais bien que ma fonction me le renvoie une fois modifié
 
j ai essayé ça :
 
double    *fonction(double  coord[3], int angle)
{
...
return (coord);
}
 
mais ca fais un joli error code
 
et ça aussi :
 
void    fonction(double *coord[3], int angle)
{
...
}
mais la il n est pas modifié
 
 
 
je pourrais le mettre dans une structure mais cette fonction ne sert pas qu a un seul endroit et j aimerais pouvoir lui passer n importe quel tableau de trois double

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)