Les double...

Résolu
cs_avalonclass Messages postés 6 Date d'inscription jeudi 14 février 2008 Statut Membre Dernière intervention 24 février 2008 - 14 févr. 2008 à 13:27
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 - 15 févr. 2008 à 10:10
Bonjour a vous, j'ai écris un ptit programme de rien du tout mais celui ci me renvoie des valeurs completement bidon quand je l'utilise... qlq'un saurait d'ou cela peu venir ?

voila le code

--------------------------------------------------------------------------------------
#include
#include <math.h>


struct Vecteur
{
       double u;
       double v;
       double w;
};


void Affvecteur(Vecteur vecteur)
{
     cout <<" u:"<< vecteur.u <<"\n;";
     cout <<" v:"<< vecteur.v <<"\n;";
     cout <<" w:"<< vecteur.w <<"\n;";
}


Vecteur Definir ( double vu,double vv,double vw )
{
        Vecteur vecteuradef;
        vu = vecteuradef.u;
        vv = vecteuradef.v;
        vw = vecteuradef.w;
        return vecteuradef;
}


int Norme ( Vecteur vecteur )
{
       double norme;
       norme=sqrt(vecteur.u*vecteur.u+vecteur.v*vecteur.v+vecteur.w*vecteur.w);
       return norme;
}


Vecteur Addition (Vecteur vecteur1, Vecteur vecteur2)
{
        Vecteur addition;
        addition.u=vecteur1.u+vecteur2.u;
        addition.v=vecteur1.v+vecteur2.v;
        addition.w=vecteur1.w+vecteur2.w;
        return addition;
}


Vecteur oppose( Vecteur vecteur)
{
        Vecteur oppose;
        oppose.u=(vecteur.u)*(-1);
        oppose.v=(vecteur.v)*(-1);
        oppose.w=(vecteur.w)*(-1);
        return oppose;
}


Vecteur soustraction (Vecteur vecteur1, Vecteur vecteur2)
{
        Vecteur resusoustr;
        resusoustr=Addition(vecteur1,oppose(vecteur2));
        return resusoustr;
}


Vecteur multiplication (Vecteur vecteur1, double multi)
{
        Vecteur resumulti;
        resumulti.u=((vecteur1.u)*multi);
        resumulti.v=((vecteur1.v)*multi);
        resumulti.w=((vecteur1.w)*multi);
        return resumulti;
}




Vecteur produitvecto(Vecteur vecteur1, Vecteur vecteur2)
{
        Vecteur resuprod;
        resuprod.u=((vecteur1.v*vecteur2.w)-(vecteur2.v*vecteur1.w));
        resuprod.v=((vecteur1.u*vecteur2.w)-(vecteur2.u*vecteur1.w));
        resuprod.w=((vecteur1.u*vecteur2.v)-(vecteur2.u*vecteur1.v));
        return resuprod;
}


int main()
{
    short unsigned choix;
    Vecteur vecteurn1;
    Vecteur vecteurn2;
    Vecteur vecteurn3;
    double u=0;
    double v=0;
    double w=0;
   
     do
     {   
         cout << " que voulez vous faire \n"
         << " 1- definir vecteur \n"
         << " 2- effectuer une multiplication \n"
         << " 3- effectuer une addition \n"
         << " 4- effectuer une soustraction \n"
         << " 5- effectuer une produit vectoriel \n"
         << " 6- multiplication par -1 \n"
         << " 7- montrer les vecteur\n"
         << " 0- quitter le programme\n";
         cout << "saisir action>";
         cin >> choix;
        
         switch (choix)
         {
                case 1:
                     cout <<" 1- definir vecteur \n";
                    
                     cout <<" vecteur numero:1\n";
                     cout <<"u:\n";
                     cin >>u;
                     cout <<"v:\n";
                     cin >>v;
                     cout <<"w:\n";
                     cin >>w;
                     vecteurn1=Definir(u,v,w);
                    
                     cout <<" vecteur numero:2\n";
                     cout <<"u:\n";
                     cin >>u;
                     cout <<"v:\n";
                     cin >>v;
                     cout <<"w:\n";
                     cin >>w;
                     vecteurn2=Definir(u,v,w);
                    
                     cout <<" vecteur numero:3\n";
                     cout <<"u:\n";
                     cin >>u;
                     cout <<"v:\n";
                     cin >>v;
                     cout <<"w:\n";
                     cin >>w;
                     vecteurn3=Definir(u,v,w);
                    
                     break;
                case 2:
                     cout <<" 2- effectuer une multiplication \n";
                    
                     break;
                case 3:
                     cout <<" 3- effectuer une addition \n";
                    
                     break;
                case 4:
                     cout <<" 4- effectuer une soustraction \n";
                    
                     break;
                case 5:
                     cout <<" 5- effectuer une produit vectoriel \n";
                    
                     break;
                case 6:
                     cout <<" 6- multiplication par -1 \n";
                     break;
                case 7:
                     cout <<" 7- voici les vecteur \n";
                     cout<<"vecteur1\n";
                     Affvecteur ( vecteurn1);
                     cout<<"vecteur2\n";
                     Affvecteur ( vecteurn2);
                     cout<<"vecteur3\n";
                     Affvecteur ( vecteurn3);
                    
                     break;
                case 0:
                     cout <<" Au revoir\n";
                    
                     break;
               
         };
     }while(choix!=0);


     system("PAUSE");


    return 0;
   
}
------------------------------------------------------------------

Je suis en train de faire les "liens" entre ma fonctions main et les divers fonctions de calcul sur les vecteurs. J'ai testé ma fonction
definir(double,double,double) et affvecteur(vecteur) cepedant l'or de laffichage avec affvecteur(vecteur) j'ai des valeurs de vecteur qui ne correspond pas du tout a ce que j'ai entré. merci d'avance pour l'aide que vous pourrez me donné.

21 réponses

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
14 févr. 2008 à 14:25
Oups non juste une correction kan meme. Dans le corps de ta fonction:
        vu vecteuradef.u;         //peut etre     vecteuradef.u vu     serai mieux ?
        vv = vecteuradef.v;
        vw = vecteuradef.w;

Tu mets le contenu du vecteur dans tes variables, c'est l'inverse qu'il faut faire:
vecteuradef.u = vu;
etc...
3
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
14 févr. 2008 à 14:31
Désolé si j'ai parru agressif, c'était pas voulu.Le probleme de ton programme c'est pas vu vecteur ou vecteur vu, ca c'est une erreur d'inatention mais le fait que tu retournes une variable locale est bien plus genant et cette erreur doit etre corrigée pour toutes les fonctions de ton programme.

Voila une version correcte:
 
void Definir (Vecteur *vecteuradef, double vu,double vv,double vw )
{
        vecteuradef->u = vu;         
        vecteuradef->v =vv;
        vecteuradef->w =vw;
      
}
et tu l'appelles avec Definir(&vect,1,1,1)

A+
Mon site internet : http://pistol.petesampras.free.fr
3
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
14 févr. 2008 à 14:44
[auteur/PISTOLPETE/352018.aspx Pistol_Pete] >> Non. Retourner une structure est parfaitement correct. Cependant, le code que tu proposes est le plus optimisé.

C++ (@++)<!--
3
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
14 févr. 2008 à 13:56
Salut
Tout ton programme est a revoir :
J'ai pas tout regardé mais ta fonction Vecteur Definir ( double vu,double vv,double vw ) est une farce:

Vecteur Definir ( double vu,double vv,double vw )
{
        Vecteur vecteuradef;        vu vecteuradef.u;         //peut etre     vecteuradef.u vu     serai mieux ?
        vv = vecteuradef.v;
        vw = vecteuradef.w;
        return vecteuradef;         //tu retournes une variable local qui sera detruit en sortie de cette fonction....
}
Utilise des allocations dynamiques ou revois le passage de parametres.

A+
Mon site internet : http://pistol.petesampras.free.fr
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_avalonclass Messages postés 6 Date d'inscription jeudi 14 février 2008 Statut Membre Dernière intervention 24 février 2008
14 févr. 2008 à 14:15
Bin a priori ma fonction definir était loin d'etre une farce puique écrire "vecteuradef.u = vu" en lieu et place de "vu = vecteuradef.u" a suffit a faire marcher le prog. Je comprends pas pourquoi TOUT le proramme est a revoir... pas la peine d'etre... agressif...
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
14 févr. 2008 à 14:24
Tsss....

Vecteur Definir ( double vu,double vv,double vw )
{
        Vecteur vecteuradef;        vu vecteuradef.u;         //peut etre     vecteuradef.u vu     serai mieux ?
        vv = vecteuradef.v;
        vw = vecteuradef.w;
        return vecteuradef;         //tu retournes une variable local qui sera detruit en sortie de cette fonction....
}
...
vecteurn1=Definir(u,v,w);

=> C'est tout a fait correct ! Très mauvais niveau performance, mais le code est correct.

J'ai pas le temps de lire en détail pour le moment.
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
14 févr. 2008 à 14:26
[auteur/PISTOLPETE/352018.aspx Pistol_Pete] >> Retourner une structure est parfaitement fonctionnel. Le compilo copira les membres de la source dans les membres de la destination.

C++ (@++)<!--
0
cs_avalonclass Messages postés 6 Date d'inscription jeudi 14 février 2008 Statut Membre Dernière intervention 24 février 2008
14 févr. 2008 à 14:30
Merci pour vos réponse. Pour le truc du "vecteuradef.u=vu" qui est != de "vu = vecteuradef.u" j'ai pas réfléchi ça marche tout de suite mieu :).
0
cs_avalonclass Messages postés 6 Date d'inscription jeudi 14 février 2008 Statut Membre Dernière intervention 24 février 2008
14 févr. 2008 à 14:48
Ok, point de vu calcul, il faut mieu utilisé les pointeurs... je savais pas, pour l'instant je m'occupe pas vraiment des soucis de performance... j'avais l'intention de passer par les pointeurs pour amélioré le prog avec une saisie dynamique du nombre de vecteur que l'on veut utilisé. D'ou lutilisation a priori inutile de beaucoup de fonction. Merci d'avoir pris le tps de regarder mon pti programme :D
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
14 févr. 2008 à 15:11
Salut,
Pour les optimisations je te conseillerai aussi d'encapsuler tes fonctions (+, -, *, opposé) dans une classe.
Tu auras aussi la possibilité de sucharger des opérateurs pour une utilisation plus aisé par la suite.
Enfin en créant une collection de vecteur tu rendra le tout dynamique et optimisé.


Bon courgae.

Shell
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
14 févr. 2008 à 16:20
Salut,


Pour le coup de Pistol_Pete -> C'est renvoyer un pointeur sur une variable globale qui est l'erreur habituelle du débutant.
typedef struct _cplusplus
{
void * c;
void * objects;
}
cplusplus;

cplusplus ReturnStruct()
{
cplusplus c;

return c;
}

cplusplus * ReturnPointer()
{
cplusplus c;

return &c;
}

int main()
{
cplusplus c;
cplusplus* pc;

c = ReturnStruct();
pc = ReturnPointer();
}


Désassemblé :
30: c = ReturnStruct();
00401278 call @ILT+60(_creer_article) (00401041)
0040127D mov dword ptr [ebp-8],eax
00401280 mov dword ptr [ebp-4],edx
31: pc = ReturnPointer();
00401283 call @ILT+55(_inserer_ville) (0040103c)
00401288 mov dword ptr [ebp-0Ch],eax


Premier cas, il recopie les 2 * 4 octets de la structure depuis le
retour vers la pile. Pas de problème (A condition de pas se soucier des
perfs).

Deuxième cas, il recopie le pointeur depuis le retour vers la pile,
mais la structure n'a pas bougé. Elle est toujours au dessus de la pile
et sera écrasée par autre chose d'ici peu.


DeAthCrAsH -> Mettre le tout dans une classe peut paraître une
"amélioration" pour une certaine quantité de personne, mais une
"optimisation", je ne pense pas que ce soit le cas, quelque soit le
compilo. Dans le meilleur des cas, les perfs seront identiques.
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
14 févr. 2008 à 16:39
Non il ne recopie pas depuis la pile. Si le nombre d'éléments présent dans la structure est négligeable (2 ou 3), il mettra le tout dans des registres puis, à la sortie, copiera des registre vers la structure.
Si il y a plus d'éléments, le compilo créera une structure "de copie" qu'il passera en paramètre à la fonction (de façon transparente) puis recopiera de cette structure de copie vers la structure destinatrice en sortie de fonction.
En gros il transforme la fonction en celle de pistol_pete puis fera une recopie dans une autre structure.

En somme, GROSSE perte de temps.

Pour ce qui est de l'encapsulation, il est vrai que ça simplifiera la programmation mais ça n'améliorera pas les performances. By desing, ce sera même l'inverse.

C++ (@++)<!--
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
14 févr. 2008 à 17:38
Bah on est d'accord il me semble.

J'ai dit "depuis le retour vers la pile". Source "le retour", destination : "la pile".

Avec ma petite structure, "le retour" était effectivement les registres eax et edx.

Et la destination ebp - 8.


Voyons ce que ça donne avec une plus grande :
typedef struct _cplusplus
{
void * c;
void * objects;
char toto[100];
}
cplusplus;

004010DE lea eax,[ebp-0DCh]
004010E4 push eax
004010E5 call @ILT+10(_ReturnStruct) (0040100f)
004010EA add esp,4
004010ED mov esi,eax
004010EF mov ecx,1Bh
004010F4 lea edi,[ebp-6Ch]
004010F7 rep movs dword ptr [edi],dword ptr [esi]


Comme tu l'as expliqué, il passe un paramètre à la fonction : un
pointeur sur une zone réservée dans la pile. Puis au retour, il copie
de pile à pile.

add esp, 4 // C'est du cdecl, faut nettoyer le paramètre poussé

mov esi, eax // On met ebp - 0DC comme source

mov ecx, 1B // La taille de ce qu'on va copier, divisée par 4 car on va copier des dword

mov edi, [ebp - 6C]  // La destination

rep movs ... // La copie


D'ailleurs ça à l'air carrément stupide. Pourquoi ne pas avoir
directement passé l'adresse de c (En gros, passé ebp - 6C à
ReturnStruct) ?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
14 févr. 2008 à 17:55
Et bien, d'après l'exemple que tu avais donnée, non on n'était pas du tout d'accord. Tu semblais même avoir confondu l'asm AT&T et Intel. En plus, dans ton précédent exemple, tu ne copiais pas DE la pile mais VERS la pile (depuis les registres).

Peut-importe, je me demande aussi la même chose.

Une réponse est que rien ne garantie qu'il y ai bien une variable qui recevra ce qui sera retourné. Dans ce cas, une structure temporaire s'impose.

Mais sinon, je l'ignore aussi. Peut-être à cause de la complexité de réaliser cette optimisation.

C++ (@++)<!--
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
14 févr. 2008 à 18:04
"tu ne copiais pas DE la pile mais VERS la pile (depuis les registres)"

"il recopie les 2 * 4 octets de la structure depuis le retour vers la pile"


Je ne vois pas la différence... J'ai dit "le retour" car je me doutais bien qu'un truc plus gros ne rentrerais pas dans les registres
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
14 févr. 2008 à 18:57
Ok dans ce cas tu as confondus AT&T et Intel. De toute façon, ton exemple était incohérent avec tes explications.
À supposer que tu utilisais l'AT&T, eax et edx ne pointe sur rien de valide.

C++ (@++)<!--
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
14 févr. 2008 à 19:29
Ces phénomènes d'incompréhension totale me mettrons toujours mal à l'aise...

Je n'ai jamais rien écrit de ma vie en AT&T, et lus pas beaucoup plus.

J'ai lus et écris suffisament de ligne d'assembleur syntaxe intel pour savoir : mov destination, source

(Mais bon je peux faire une faute d'inattention.)


Citation de plus haut, assembleur récupéré en copier coller depuis VC6 (Et donc désassemblé par lui) :
0040127D mov dword ptr [ebp-8],eax
00401280 mov dword ptr [ebp-4],edx

Source : les valeurs des registres eax et edx.

Destination : valeur pointée par l'adresse calculée en prenant le contenu du registre ebp et en lui soustrayant 8.

Le compilo fait renvoyer le résultat de ReturnStruct dans eax:edx
conformément à la convention cdecl et le tout est recopié dans les
variables locales.

C'est tout à fait ce que tu as dit.

Mais c'est aussi tout à fait ce que j'ai dit, depuis le début.

Après, je me suis peut être encore plus mal exprimé que d'habitude...

Une phrase en particulier de chiffone dans mon premier post (Si oui, laquelle ?), ou tout te paraît incohérent ?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
15 févr. 2008 à 00:01
OUPS !!!!

La phrase étant:
"Premier cas, il recopie les 2 * 4 octets de la structure depuis le retour vers la pile."
Mon cerveau la tout simplement remplacé par:
"Premier cas, il recopie les 2 * 4 octets de la structure depuis le retour à partir de la pile."

J'ai lus beaucoup trop vite et comme il y avait un saut de ligne (sur mon écran) entre "depuis le retour" et "vers la ligne", j'ai tout simplement sauté "vers" et remplacer par autre chose pour donner une phrase correct.
Et là je me suis construit tout une histoire en pensant que tu avais confondus AT&T et Intel et que tu avais zappé un truc important......

Pfffff.....
Au moins, cette confusion de ma part aura permit d'approfondir ce que fait le compilo avec les structures.

Donc OUI rt15, ton exemple est correct et OUI tes explications sont cohérentes.

C++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
15 févr. 2008 à 00:09
"entre "depuis le retour" et "vers la ligne""
C'est
"entre "depuis le retour" et "vers la pile""

Enfait, j'ignore si c'est le saut de ligne ou que je n'ai pas correctement interprété ce bout de phrase:
"Premier cas, il recopie les 2 * 4 octets de la structure depuis le retour vers la pile."

Peut-être les 2.

En gros, je crois plutôt que j'ai supprimer le "le retour vers" à cause du sens vague que prend le bout de phrase. (le retour de quoi ?)
Ceci donna donc:
"Premier cas, il recopie les 2 * 4 octets de la structure depuis la pile."

En tout cas, il y a eu confusion de ma part.

C++ (@++)<!--
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
15 févr. 2008 à 09:42
rt15> Une optimisation ne se qualifie pas seulement par le gain en performance en terme de temps d'execution. Du code optimisé, c'est à mon sens du code facilement réutilisable, lisible, et gérant des temps d'execution suffisement rapide pour ce qu'on lui demande.
On n'a jamais vu renault créer des clio avec des moteurs de ferrari.

Un bon programmeur doit avant tout limiter ses choix et ses actions au périmètre de son application.

Shell
0
Rejoignez-nous