[C++] problème étrange

problème étrange [C++] - C++ - Programmation

Marsh Posté le 01-01-2004 à 21:38:48    

rebonjour,
voilà, j'ai ça :

Code :
  1. void traitement(int t,machine M[9],chariot C)
  2. {
  3.     int tmp_attente=0;int tmp_machine=0;
  4.     int appel=0;
  5.    
  6.     for(int i=0;i<9;i++)
  7.     {
  8.         if(M[i].etat_machine() == ATTENTE_PIECE)
  9.         {
  10.                 M[i].alimenter_machine(t);
  11.         }
  12.         else if(M[i].etat_machine() == USINAGE_PIECE)
  13.         {
  14.                 M[i].verification_usinage(t);
  15.         }
  16.         else if(M[i].etat_machine() == ATTENTE_CHARIOT)
  17.         {
  18.                 M[i].incremente_attente();
  19.                 if(M[i].attente()>tmp_attente)
  20.                 {
  21.                                 tmp_attente=M[i].attente();
  22.                                 tmp_machine=i;
  23.                 }
  24.                 appel=1;
  25.         }
  26.     }
  27.    
  28.     if(C.etat_chariot() == ATTENTE && appel != 0)
  29.     {
  30.         C.nouvelle_destination(M[tmp_machine]);
  31.     }
  32.     if(C.etat_chariot() == EN_ROUTE)
  33.     {
  34.         C.deplacer();
  35.     }
  36. }


 
j'appelle la fonction traitement dans le main.  
Lors de l'appel de C.nouvelle_destination() (en bas), cette fonction devrait changer une variable protected de la classe chariot (qui se nomme etat), et qui est retrouvée par C.etat_chariot().
Or, elle n'est pas mise à jour du tout.
 
si je recopie la fonction traitement dans le main, ça marche.
 
c'est très étrange, parce que je fais exactement la même chose avec la variable M[i] un peu plus haut, avec la fonction alimenter_machine(), et là ça marche :/...
 
quelqu'un aurait une idée ? (dsl, j'arrive pas à exprimer très clairement le problème)
 
Merci d'avance ! :hello:


Message édité par Gurney_Halleck le 01-01-2004 à 21:44:11
Reply

Marsh Posté le 01-01-2004 à 21:38:48   

Reply

Marsh Posté le 01-01-2004 à 21:47:09    

ben ne passe pas ton chariot pas copie mais par référence.
sinon utilise plutot un switch et des bool

Reply

Marsh Posté le 01-01-2004 à 21:56:32    

taz a écrit :

ben ne passe pas ton chariot pas copie mais par référence.
sinon utilise plutot un switch et des bool


 
euh :whistle:  
tu peux juste m'expliquer ce qu'est "par référence" ?

Reply

Marsh Posté le 01-01-2004 à 22:00:23    

j'ai trouver c bon :)

Reply

Marsh Posté le 01-01-2004 à 22:05:21    

voilà ce que j'ai fait :)
 

Code :
  1. void traitement(int t,machine M[9],chariot &C)
  2. {
  3.     int tmp_attente=0;int tmp_machine=0;
  4.     bool appel=false;
  5.    
  6.     for(int i=0;i<9;i++)
  7.     {
  8.         switch(M[i].etat_machine()){
  9.         case ATTENTE_PIECE:
  10.                 M[i].alimenter_machine(t);
  11.                 break;
  12.        
  13.         case USINAGE_PIECE:
  14.                 M[i].verification_usinage(t);
  15.                 break;
  16.         case ATTENTE_CHARIOT:
  17.                 M[i].incremente_attente();
  18.                 if(M[i].attente()>tmp_attente)
  19.                 {
  20.                                 tmp_attente=M[i].attente();
  21.                                 tmp_machine=i;
  22.                 }
  23.                 appel=true;
  24.                 break;
  25.         }
  26.     }
  27.    
  28.     if(C.etat_chariot() == ATTENTE && appel)
  29.     {
  30.         C.nouvelle_destination(M[tmp_machine]);
  31.     }
  32.     if(C.etat_chariot() == EN_ROUTE)
  33.     {
  34.         C.deplacer();
  35.     }
  36. }


 
merci taz :hello:  
 
c marrant, parce que le compilateur à l'air de considérer l'objet machine comme un pointeur, alors que le chariot, non...
 
y aurait une explication ?

Reply

Marsh Posté le 01-01-2004 à 22:14:15    

heink ?

Reply

Marsh Posté le 01-01-2004 à 22:50:01    

Gurney_Halleck a écrit :


y aurait une explication ?


je vais essayer en deux lignes, parce que j'ai pas que ça à foutre:
machine M[9]: M contient l'addresse du tableau passé en paramètre
chariot &C: C est une référence (quasi pointeur) sur l'objet passé en paramètre (et non une recopie comme ca serait le cas si l'escargoulette '&' n'était pas utilisée)


Message édité par schnapsmann le 01-01-2004 à 22:53:23

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 01-01-2004 à 22:54:28    

non non et non. les tableaux ne sont pas des lvalues,
la vérité, c'est que t'es complètement perdu entre référence, pointeur, notation (*, [], et [N])
 
 
en clair: un tableau ne peut être copié, donc
 
T *tab, T tab[], et T tab[N] ont le même emploi : dans tous les cas, aucune recopie n'est effectuée,


Message édité par Taz le 01-01-2004 à 22:59:04
Reply

Marsh Posté le 01-01-2004 à 22:59:52    

taz a écrit :

non non et non. les tableaux ne sont pas des lvalues,
la vérité, c'est que t'es complètement perdu entre référence, pointeur, notation (*, [], et [N])


 
tu te fous de qui?


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 01-01-2004 à 23:00:59    

ce que je voulais dire :
 
en fait, le tableau avait l'air d'être, par défaut, considérer comme un pointeur, alors que je n'avais rien indiquer. Par contre, C était considéré comme un paramètre normal.
 
donc je voulais savoir si il y avait une raison, c tout :)
 
et je suis certainement perdu entre référence, pointeur, et notation...
vàlà


Message édité par Gurney_Halleck le 01-01-2004 à 23:02:14
Reply

Marsh Posté le 01-01-2004 à 23:00:59   

Reply

Marsh Posté le 01-01-2004 à 23:01:11    

Code :
  1. #include <iostream>
  2. #include <typeinfo>
  3. template<typename T>
  4. void info(const T &x)
  5. {
  6.   std::cout << x << ' '
  7.     << typeid(x).name() << '\n'; 
  8. }
  9. void un(int a[10])
  10. {
  11.   info(a);
  12. }
  13. void deux(int a[])
  14. {
  15.   info(a);
  16. }
  17. void trois(int *a)
  18. {
  19.   info(a);
  20. }
  21. int main()
  22. {
  23.   int a[10];
  24.   info(a); un(a); deux(a); trois(a);
  25.   int b[5];
  26.   info(b); un(b); deux(b); trois(b);
  27. }


comme tu peux le voire, les trois appels aboutissent au même résultat : le paramètre a est un pointeur d'entiers

Reply

Marsh Posté le 01-01-2004 à 23:02:01    

Gurney_Halleck a écrit :

en fait, le tableau avait l'air d'être, par défaut, considérer comme un pointeur, alors que je n'avais rien d'indiquer. Par contre, C était considéré comme un paramètre normal.

tout ce qui est dit est valable également pour le C

Reply

Marsh Posté le 02-01-2004 à 01:30:51    

taz a écrit :

Code :
  1. #include <iostream>
  2. #include <typeinfo>
  3. template<typename T>
  4. void info(const T &x)
  5. {
  6.   std::cout << x << ' '
  7.     << typeid(x).name() << '\n'; 
  8. }
  9. void un(int a[10])
  10. {
  11.   info(a);
  12. }
  13. void deux(int a[])
  14. {
  15.   info(a);
  16. }
  17. void trois(int *a)
  18. {
  19.   info(a);
  20. }
  21. int main()
  22. {
  23.   int a[10];
  24.   info(a); un(a); deux(a); trois(a);
  25.   int b[5];
  26.   info(b); un(b); deux(b); trois(b);
  27.   return 0; // <== il faudrait pas l'oublier, pour faire plaisir au compilo
  28. }


comme tu peux le voire, les trois appels aboutissent au même résultat : le paramètre a est un pointeur d'entiers

[:chacal_one333]
A+,


Message édité par gilou le 02-01-2004 à 01:32:45

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-01-2004 à 10:03:00    

Citation :

return 0; // <== il faudrait pas l'oublier, pour faire plaisir au compilo


en C++ (et C99), la norme dit clairement que si on omet le return final (pourtant obligatoire puisque main doit retourner un int), le compilateur __doit__ générer ce qu'il faut pour qu'une valeur signifiant une terminaison correct du programme soit retournée au système.

Reply

Marsh Posté le 02-01-2004 à 10:20:47    

Vi c'est pourquoi j'ai dit que c'etait pour faire plaisir au compilo: ca lui evite de faire le boulot et (surtout) de balancer un warning.  
Moi je suis pour la minimisation des warnings, et pas a coup de pragmas :D
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-01-2004 à 10:23:06    

euh le warning c'est par ce que t'as un compilateur bouseux, c'est tout. N'importe quel compilateur capable de respecter une règle si simple n'emettra jamais aucun warning

Reply

Marsh Posté le 02-01-2004 à 12:14:32    

La norme dit en effet:

Citation :

If  control  reaches  the end  of  main  without  encountering a return statement, the effect is that of executing return 0;


Au fait, apres avoir pas mal browse le draft iso, je suis preneur de la suite de regle etablissant que une une fonction (autre que main) declaree avec un type de retour different de void, mais sans statement return dans le corps de la fonction provoque une erreur a la compilation [les regles etablissant pourquoi ca provoque une erreur a l'execution par contre, je les vois]
 
 
Je ne trouve pas que l'emission d'un warning soit en quoi que ce soit le fait d'un compilo bouseux en ce cas precis. Au contraire, c'est l'exemple typique d'un warning utile:
Signaler quelque chose qui n'est pas une erreur effective pour le compilateur, mais est une erreur potentielle (ne pas mettre de valeur de retour a une fonction retournant un int peut etre le fait soit d'un programmeur qui le fait en connaissance de cause pour le main, soit le fait d'un programmeur qui a effectivement oublie de retourner un code d'erreur.)
 
De plus personnellement, je n'aime pas cette convention, bien que je voie clairement pourquoi elle a ete mise en place (un compromis). Autant prendre d'emblée de bonnes habitudes et mettre un return statement a toute fonction declaree avec un type de retour autre que void. Ce genre de convention ca ouvre la porte a plein de choses qui rapelle les debuts du C: pourquoi ne pas l'etendre a toute fonction retournant un int? ou tout autre type numerique? etc... (bon, je me fais l'avocat du diable, là)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-01-2004 à 12:18:44    

non. c'est juste une petite facilité pour débuter les fouteurs de merde qui font du C et qui préfèrent (en < C99) void main, parce que soit disant int main/return 0; c'est trop long. donc on leur a fait une fleur, et ils font meme l'économie d'un caractère. en plus pour le cas de main, je trouve ça intelligent: le retour de main n'a d'importance qui si on souhaite signaler des erreurs au contexte appelant. au cas contraire, on se tourne les pouces et tout va bien.

Reply

Marsh Posté le 02-01-2004 à 13:08:07    

J'escomptais surtout une reponse a ma question dans le premier paragraphe (parce que j'ai bien cherche dans le Draft ISO sans trouver la reponse)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-01-2004 à 13:12:50    

j'ai un peu la flemme là :sweat:

Reply

Marsh Posté le 02-01-2004 à 13:30:19    

[:totoz]
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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