[C] : Une fonction peut elle renvoyer un tableau ??

: Une fonction peut elle renvoyer un tableau ?? [C] - Programmation

Marsh Posté le 27-02-2001 à 21:43:38    

Voir son adresse ?

Reply

Marsh Posté le 27-02-2001 à 21:43:38   

Reply

Marsh Posté le 27-02-2001 à 22:41:56    

oui c'est tout à fait possible, mais en pratique tu n'as pas du tout intérêt à surcharger la pile, il vaut 1000 fois mieux passer par un pointeur ou une référence.

 

--Message édité par z51--

Reply

Marsh Posté le 27-02-2001 à 22:57:27    

En général, oui, mais en C, un tableau est déjà un pointeur, donc il n'y a même aucun risque d'exploser la pile...

Reply

Marsh Posté le 27-02-2001 à 23:00:40    

surtout son adresse ...

Reply

Marsh Posté le 28-02-2001 à 09:39:35    

euh... retourner un tableau c retourner une adresse :D


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
Reply

Marsh Posté le 28-02-2001 à 17:06:34    

ex :
 
int* retournetableau()
{
int tab[5] = {0};
return tab;
}
la fonction retourne l'adresse du pointeur tab soit l'adresse du premier element du tableau soit l'adresse de tab[0].

Reply

Marsh Posté le 28-02-2001 à 17:23:48    

Oui mais là c'est très dangereux, tu retourne l'adresse d'une variable locale !

Reply

Marsh Posté le 28-02-2001 à 18:24:11    

C'est clair la viper ->
ne retourne jamais l'adresse d'une var locale !
Soit tu passes le tableau en paramètre de ta fonction, soit tu fais de l'allocation dynamique à l'intérieur (mais c'est crade)

Reply

Marsh Posté le 28-02-2001 à 18:30:24    

le mieux c de faire faire passer un tableau en parametre...
Comme ca ta fonction est dechargée de tout ce ki est gestion de memoire... et elle peut donc se concentrer sur son but...


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
Reply

Marsh Posté le 28-02-2001 à 20:14:18    

Je ne comprends pas pourquoi c'est crade d'allouer dynamiquement à l'intérieur de la fonction ? Pour moi ca revient au même .

Reply

Marsh Posté le 28-02-2001 à 20:14:18   

Reply

Marsh Posté le 28-02-2001 à 20:24:33    

Dans ce cas, il faut bien se souvenir qu'on a alloué de la mémoire avec cette fonction et penser à la libérer sinon ça fuit.

Reply

Marsh Posté le 28-02-2001 à 21:06:48    

effectivement j'ai pas trop reflechi là !!!
toutes mes escuses ..
int* EnDynamique(int valeur)
{
int* ptr = (int)malloc(valeur*sizeof(int));
return ptr;
}
 
Le seul reproche qui est a faire ici est qu'on passe par deux pointeur. Et que dans ce cas là, on aura p etre un probleme d'adresse a remettre à jour si on agrandit la zone de memoire alouée à ptr.
 
bref, ct juste pour montrer que ct possible et que d'ailleur il est recommandé de faire des passages d'adresse plutot que de variable! vous confirmez ??

Reply

Marsh Posté le 28-02-2001 à 21:40:06    

Je ne pensais pas provoquer un tel débat ??
J'm'aperçois qu'il y a des C(iens) avertis dans ce forum -> Tant mieux parceque pour ma part c'est le démarrage et j'ai encore du chemin à faire mais j'aime bien ça.
 
Le but de ma question était de savoir si je pouvais envoyer 2 vecteurs à une fct et de lui demander m'en rendre la somme ou le produit.
Dailleur cette adresse en retour, je peux l'affecter à un autre tableau directement(:ouch: ) ou pluôt lui faire pointer un int *.    
 
Merci à vous tous pour votre aide

Reply

Marsh Posté le 28-02-2001 à 23:53:49    

moi je ferais ca !
 
struct vecteur
{
int i,j,k;
}
 
vecteur somme(vecteur A, vecteur B);
vecteur produit(vecteur A,vecteur B);
 
void main(void)
{
vecteur A,B,C,D;
C = somme(A,B);
D = produit(A,B);
}
 
vecteur somme(vecteur A,vecteur B)
{
vecteur tmp;
tmp.i = A.i + B.i;
tmp.j = A.j + B.j;
tmp.k = A.k + B.K;
 
return tmp;
}
 
idem pour produit
 
ici pas besoin de tableau et de pointeur !!

Reply

Marsh Posté le 01-03-2001 à 00:07:17    

Merci à toi grande Viper
 
Même pas le temps de finir de tester une fonction que m'a envoiée BifaceMcLeOD sur un autre sujet que voila une réponse à cette question (Qui + est Avé le code)
 
C'est vraiment le pied  
 
Merci beaucoup

Reply

Marsh Posté le 01-03-2001 à 00:19:58    

la viper a écrit :
 
>>>vecteur somme(vecteur A,vecteur B)  
>>>{  
>>>  vecteur tmp;:hot:  
>>>  tmp.i = A.i + B.i;  
>>>  tmp.j = A.j + B.j;  
>>>  tmp.k = A.k + B.K;  
>>>  return tmp;:gun:
>>>}  
 
en C, à moins de déclarer une variable static, elle est détruite à la fin du bloc où elle est déclarée, donc ici pour utiliser le résultat dans main ça risque d'être catastrophique
 
personnellement je passerais en paramètres les adresses des 2 tableaux à sommer + l'adresse du tableau résultat, à alouer évidemment avant l'appel

Reply

Marsh Posté le 01-03-2001 à 01:29:05    

oh_damned> Oui, mais la structure est retournée, donc une copie en sera faite avant, et c'est cette copie qui sera utilisée par le main. Ce n'est pas comme si on retournait un pointeur sur cette structure locale...
 
Le seul inconvénient à retourner une structure, c'est que ce n'est pas d'une efficacité à toute épreuve. Mais quand on débute en programmation, c'est la dernière chose à laquelle penser ! :D

Reply

Marsh Posté le 01-03-2001 à 10:26:06    

c bien vrai... vaut mieu eviter de prendre cette habitude au depart... car une structure est tellement variable!!!
Kom je lai dit plus haut.. je prefere la soluce de damned.
Car ta fonction n'est pas sensée toucher koi ke ce  soi a la memoire... au nivo alloc


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
Reply

Marsh Posté le 01-03-2001 à 10:53:47    

Ou faire un truc du genre
 
int* retournetableau()  
{  
static int tab[5] = {0};  
return tab;  
}


---------------
"If you can walk away from a landing, it's a good landing. If you use the airplane the next day, it's an outstanding landing." - Chuck Yeager. | Chaîne YT | Photos
Reply

Marsh Posté le 01-03-2001 à 11:01:13    

:)


---------------
"C'est le boulot qu'on ne commence jamais qui est le plus long à terminer"
Reply

Marsh Posté le 01-03-2001 à 20:41:08    

vous vous prenez vraiment le choux les mecs !!! effectivement renvoyer une structure de hum ... 3*2 octets .. soit 6 octets au lieu d'un pointeur de 4 octets ca vaut vachement le coup !!! :eek2:  
 
parfois, il faut faire abstration de tous ces petits probleme pour aller au plus simple .. j'vous promet que meme un 286 ne vera pas la difference.

Reply

Marsh Posté le 01-03-2001 à 21:00:51    

tu devrais essayer le C++ , car la surcharge d'operateur ( ici l'operateur + , * et = ) c'est super pratique. En effet dans le code c'est mieux de mettre C = A + B ou C = A * B plutot que C = somme(A,B) ou C = produit(A,B).

Reply

Marsh Posté le 01-03-2001 à 22:42:16    

xilebo>
Tu pourrais me mettre un exemple, je sais pas faire:)


---------------
http://www.cheata.net le site qui vous donne la banane!
Reply

Marsh Posté le 01-03-2001 à 23:51:21    

La surcharge d'opérateur, c'est très pratique, mais ça peut finir par être dangereux, car on finit par ne plus savoir ce que l'on fait.
Croyez-en mon expérience... pour avoir vu des programmeurs redéfinir les opérateurs new et delete. Là, ça commence à devenir plus intéressant d'acheter des actions dans les fabricants d'aspirine...  ;)

Reply

Marsh Posté le 01-03-2001 à 23:56:49    

surtout pour une fonction qui n'a pour vocation que d'additionner deux structures de 2 entiers !!!!!!
 
Faut pas se prendre la tete !!!  
 
toujours aller au plus simple et ou plus facile a coder  
 
car :
- moins de ligne de code
- moins de bourrage de tete
 
et donc moins de BUG !

Reply

Marsh Posté le 02-03-2001 à 01:06:32    

la viper> C'est le bon sens même ! :sol:

Reply

Marsh Posté le 02-03-2001 à 12:55:22    

Allez un ch'tit exemple pour ma culture :p


---------------
http://www.cheata.net le site qui vous donne la banane!
Reply

Marsh Posté le 02-03-2001 à 14:59:26    

En reprendrenant l'exemple de Viper :
 
vecteur operator+(vecteur const &A, vecteur const &B)  
{  
vecteur tmp;  
tmp.i = A.i + B.i;  
tmp.j = A.j + B.j;  
tmp.k = A.k + B.K;  
 
return tmp;  
}  
 
Et après tu peux directement écrire : A = B + C
où A, B et C sont trois vecteurs.
 
Sur des structures plus importantes (les matrices par ex) la surcharge est assez pénalisante, mais c'est tellement plus lisible ...

Reply

Marsh Posté le 02-03-2001 à 20:31:54    

z51> Je me demande si operator+() ne doit pas renvoyer une référence...
 
Sinon, si vous voulez faire dans l'optimisé dans vos redéfinitions d'opérateurs, je vous conseille d'implémenter operator+=() d'abord, puis appeler operator+=() dans l'implémentation d'operator+(). Et pas le contraire (i.e. appeler operator+() dans l'implémentation d'operator+=()). Ainsi :
 
vecteur& vecteur::operator+=(vecteur const& a)
{
    this->i += a.i;
    this->j += a.j;
    this->k += a.k;
 
    return this;
}
 
vecteur& vecteur::operator+(vecteur const& a, vecteur const b)
{
    vecteur  result(a);
 
    result += b;
    return result;
}
 
Bien sûr il ne faut avoir oublié le constructeur par recopie :
vecteur::vecteur(vecteur const& a)
    : i(a.i), j(a.j), k(a.k)
{
}
 
Avantage: operator+() ne change pas, mais operator+=() ne requiert pas de mémoire supplémentaire (=> plus optimisé).

Reply

Marsh Posté le 02-03-2001 à 21:06:32    

Euh là ça va pas le faire.
Déja le premier opérateur doit retourner *this.
 
Ensuite le second définit un opérateur ternaire et en plus retourne une référence sur un temporaire.

Reply

Marsh Posté le 02-03-2001 à 21:13:10    

C'est bon merci les gars j'ai capté :jap:


---------------
http://www.cheata.net le site qui vous donne la banane!
Reply

Marsh Posté le 02-03-2001 à 22:29:04    

Verdoux a écrit a écrit :

Euh là ça va pas le faire.
Déja le premier opérateur doit retourner *this.
 
Ensuite le second définit un opérateur ternaire et en plus retourne une référence sur un temporaire.




Oups! J'ai oublié une étoile dans mon premier return... :D (preuve que j'ai tapé ce code sans même le compiler !)
 
Par contre, pour l'opérateur ternaire, je ne suis pas d'accord : en général, quand on écrit le proto tel que je l'ai écrit (sauf qu'il ne doit pas renvoyer pas de référence, là, je te donne raison), c'est que l'opérateur est friend ! Mais bon, on peut aussi le déclarer non-friend et ne mettre qu'un seul paramètre... ;)
 
Bon, je vais quand même corriger ce code tout plein d'erreurs : :D
 
vecteur& vecteur::operator+=(vecteur const& a)
{
    this->i += a.i;
    this->j += a.j;
    this->k += a.k;
 
    return *this;
}
 
vecteur vecteur::operator+(vecteur const& a) const
{
    vecteur  result(*this);
 
    result += b;
    return result;
}

Reply

Marsh Posté le 02-03-2001 à 22:41:16    

Oui mais si il est friend, il est en dehors de la classe. Donc il s'appelle pas vecteur::operator+ mais simplement operator+ :)

Reply

Marsh Posté le 02-03-2001 à 22:46:54    

Arrête moi si je me trompe, mais ça n'optimise en rien l'opérateur +() d'appeler +=()
Ca le ralentit même si tes fonctions ne sont pas inline.

Reply

Marsh Posté le 02-03-2001 à 23:01:49    

Ouais c'est pas très optimal.
Mais pour faire des truc assez efficace, il faut pas mal réfléchir.
Un exemple de librairie optimisée:
http://www.oonumerics.org/blitz/
 
Ca permet d'écrire des trucs du genre:
Array<float,2> A(64,64), B(64,64);   // 2 matrices 64x64
Range I(1,62), J(1,62); // on définit 2 indices avec leurs plages.
 
// et on peut calculer par exemple:
A(I,J) = (B(I,J) + B(I+1,J) + B(I-1,J)  
                 + B(I,J+1) + B(I,J-1)) / 5;
 
Cette dernière écriture est vraiment très proche de ce qu'on écrit mathématiquement.  
Et l'évaluation est très efficace car on ne fait que 2 boucles (l'une sur I, l'autre sur J) alors que si on prend des opérateurs définis "simplement", le calcul de A+B+C+D+E est évalué en A + (B + (C + (D + E))) soit 4x2 boucles.

 

--Message édité par Verdoux--

Reply

Marsh Posté le 03-03-2001 à 00:20:52    

Verdoux> Yep, tu as (encore) raison, le "vecteur::" était de trop !
 
Je sens que je vais arrêter de répondre aux questions C++, moi, ça fait trop longtemps que je n'en ai pas fait.
 
z51> Rien ne dit que les fonctions que j'ai écrites sont ou non sont pas inline (puisqu'il manque la définition de la classe elle-même). Mais ce qu'elles sont censées optimiser, ces fonctions, c'est la consommation mémoire (le += ne consomme rien). Et puis il n'est pas évident que l'appel de fonction que tu souhaite économiser soit vraiment pénalisant. Comme l'a souligné Verdoux au sujet des matrices, il y a d'autres "optimisations" beaucoup plus efficaces en modifiant carrément l'interface et les algorithmes.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed