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

  FORUM HardWare.fr
  Programmation
  C

  probleme pour permutter 2 entiers par adresse...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

probleme pour permutter 2 entiers par adresse...

n°481049
neo9205
Posté le 08-08-2003 à 14:41:31  profilanswer
 

:hello:  ,J'ai fait le petit test d'échange de valeurs suivant :
 
void swap(int *a,int *b);
 
void main()
{
int a,b;
int *aa=&a;
int *bb=&b;
a=3,b=5;
printf("contenu de a: %d ,contenu de b: %d\n",a,b);
swap(aa,bb);//permutation...
printf("contenu de a apres permutation: %d\t,contenu de b apres permutation: %d\n",*aa,*bb);
}
 
 
void swap(int *x,int *y)//passage des parametres par adresse
{
 
int *temp;
printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
printf("adresse de x: %x ,adresse de y: %x,adresse de temp: %x\n",x,y,temp);
 
//permutation des adresses ou pointe les pointeurs
temp=x;
x=y;
y=temp;
 
printf("adresse de x: %x ,adresse de y: %x\n",x,y);
printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
}
 
 
Dans la fonction swap() tout est bien permuté aussi bien les adresses que les contenus.Par contre de retour dans le main, "a" et "b" ne sont pas permuttés ! Mais pourquoi alors que j'ai transmis a et b par leurs adresses quand j'ai appelé la fonction swap().Je sais que si je transforme la fonction swap() comme ci apres  
 
*temp=*x;
*x=*y;
*y=*temp;
 
ça fonctionne mais je veux échanger par adresse dans swap() et non par contenu de pointeur.Comment dois je m'y prendre ??? j'ai oublié un détail peut etre ??
 
D'avance merci pour votre aide  :hello:  

mood
Publicité
Posté le 08-08-2003 à 14:41:31  profilanswer
 

n°481056
LetoII
Le dormeur doit se réveiller
Posté le 08-08-2003 à 14:45:03  profilanswer
 

neo9205 a écrit :

:hello:  ,J'ai fait le petit test d'échange de valeurs suivant :
 
void swap(int *a,int *b);
 
void main()
{
int a,b;
int *aa=&a;
int *bb=&b;
a=3,b=5;
printf("contenu de a: %d ,contenu de b: %d\n",a,b);
swap(aa,bb);//permutation...
printf("contenu de a apres permutation: %d\t,contenu de b apres permutation: %d\n",*aa,*bb);
}
 
 
void swap(int *x,int *y)//passage des parametres par adresse
{
 
int *temp;
printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
printf("adresse de x: %x ,adresse de y: %x,adresse de temp: %x\n",x,y,temp);
 
//permutation des adresses ou pointe les pointeurs
temp=x;
x=y;
y=temp;
 
printf("adresse de x: %x ,adresse de y: %x\n",x,y);
printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
}
 
 
Dans la fonction swap() tout est bien permuté aussi bien les adresses que les contenus.Par contre de retour dans le main, "a" et "b" ne sont pas permuttés ! Mais pourquoi alors que j'ai transmis a et b par leurs adresses quand j'ai appelé la fonction swap().Je sais que si je transforme la fonction swap() comme ci apres  
 
*temp=*x;
*x=*y;
*y=*temp;
 
ça fonctionne mais je veux échanger par adresse dans swap() et non par contenu de pointeur.Comment dois je m'y prendre ??? j'ai oublié un détail peut etre ??
 
D'avance merci pour votre aide  :hello:  
 


 
 :heink:  

Code :
  1. void swap(int **a,int **b);
  2. void main()
  3. {
  4. int a,b;
  5. int *aa=&a;
  6. int *bb=&b;
  7. a=3,b=5;
  8. printf("contenu de a: %d ,contenu de b: %d\n",a,b);
  9. swap(aa,bb);//permutation...
  10. printf("contenu de a apres permutation: %d\t,contenu de b apres permutation: %d\n",*aa,*bb);
  11. }
  12. void swap(int **x,int **y)//passage des parametres par adresse
  13. {
  14. int *temp;
  15. printf("contenu de x: %d ,contenu de y: %d\n",**x,**y);
  16. printf("adresse de x: %x ,adresse de y: %x,adresse de temp: %x\n",*x,*y,temp);
  17. //permutation des adresses ou pointe les pointeurs
  18. temp=*x;
  19. *x=*y;
  20. *y=*temp;
  21. printf("adresse de x: %x ,adresse de y: %x\n",*x,*y);
  22. printf("contenu de x: %d ,contenu de y: %d\n",**x,**y);
  23. }

n°481109
neo9205
Posté le 08-08-2003 à 15:06:45  profilanswer
 

LetoII a écrit :


 
 :heink:  

Code :
  1. void swap(int **a,int **b);
  2. void main()
  3. {
  4. int a,b;
  5. int *aa=&a;
  6. int *bb=&b;
  7. a=3,b=5;
  8. printf("contenu de a: %d ,contenu de b: %d\n",a,b);
  9. swap(aa,bb);//permutation...
  10. printf("contenu de a apres permutation: %d\t,contenu de b apres permutation: %d\n",*aa,*bb);
  11. }
  12. void swap(int **x,int **y)//passage des parametres par adresse
  13. {
  14. int *temp;
  15. printf("contenu de x: %d ,contenu de y: %d\n",**x,**y);
  16. printf("adresse de x: %x ,adresse de y: %x,adresse de temp: %x\n",*x,*y,temp);
  17. //permutation des adresses ou pointe les pointeurs
  18. temp=*x;
  19. *x=*y;
  20. *y=*temp;
  21. printf("adresse de x: %x ,adresse de y: %x\n",*x,*y);
  22. printf("contenu de x: %d ,contenu de y: %d\n",**x,**y);
  23. }




 
tu n'as pas compris ce que je voulais vraiment...En fait je veux que la fonction swap()contienne ceci :
temp=x;
x=y;
y=temp;
 
//Et qu'elle fonctionne bien sur vis à vis du main()->permutation correcte
 
Et pas cela:
temp=*x;
*x=*y;
*y=*temp;
 
 

n°481120
LetoII
Le dormeur doit se réveiller
Posté le 08-08-2003 à 15:12:56  profilanswer
 

Faut dire ct pas clair
 

Code :
  1. void swap(int *a,int *b);
  2. void main()
  3. {
  4. int a,b;
  5. int *aa=&a;
  6. int *bb=&b;
  7. a=3,b=5;
  8. printf("contenu de a: %d ,contenu de b: %d\n",a,b);
  9. swap(aa,bb);//permutation...  
  10. printf("contenu de a apres permutation: %d\t,contenu de b apres permutation: %d\n",*aa,*bb);
  11. }
  12. void swap(int *x,int *y)//passage des parametres par adresse  
  13. {
  14. int temp;
  15. printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
  16. printf("adresse de x: %x ,adresse de y: %x,adresse de temp: %x\n",x,y,temp);
  17. //permutation des adresses ou pointe les pointeurs  
  18. temp=*x;
  19. *x=*y;
  20. *y=temp;
  21. printf("adresse de x: %x ,adresse de y: %x\n",x,y);
  22. printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
  23. }


Message édité par LetoII le 08-08-2003 à 15:13:31

---------------
Le Tyran
n°481195
neo9205
Posté le 08-08-2003 à 15:57:14  profilanswer
 

LetoII a écrit :

Faut dire ct pas clair
 

Code :
  1. void swap(int *a,int *b);
  2. void main()
  3. {
  4. int a,b;
  5. int *aa=&a;
  6. int *bb=&b;
  7. a=3,b=5;
  8. printf("contenu de a: %d ,contenu de b: %d\n",a,b);
  9. swap(aa,bb);//permutation...  
  10. printf("contenu de a apres permutation: %d\t,contenu de b apres permutation: %d\n",*aa,*bb);
  11. }
  12. void swap(int *x,int *y)//passage des parametres par adresse  
  13. {
  14. int temp;
  15. printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
  16. printf("adresse de x: %x ,adresse de y: %x,adresse de temp: %x\n",x,y,temp);
  17. //permutation des adresses ou pointe les pointeurs  
  18. temp=*x;
  19. *x=*y;
  20. *y=temp;
  21. printf("adresse de x: %x ,adresse de y: %x\n",x,y);
  22. printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
  23. }




 
Y a plus d'étoile à temp mais y en a encore à x et y ce que je ne veux pas.

n°481227
LetoII
Le dormeur doit se réveiller
Posté le 08-08-2003 à 16:05:30  profilanswer
 

:heink: Tu peux pas faire autrement hein


---------------
Le Tyran
n°481267
Taz
bisounours-codeur
Posté le 08-08-2003 à 16:21:25  profilanswer
 

LetoII a écrit :

:heink: Tu peux pas faire autrement hein  

les pointeurs c'est pas sal!

n°481390
LetoII
Le dormeur doit se réveiller
Posté le 08-08-2003 à 17:48:54  profilanswer
 

Taz a écrit :

les pointeurs c'est pas sal!


 
J'ai jamais dit le contraire mais soit il s'exprime mal soit il a déjà la solution  [:spamafote]


---------------
Le Tyran
n°481426
theshockwa​ve
I work at a firm named Koslow
Posté le 08-08-2003 à 19:37:17  profilanswer
 

LetoII a écrit :


 
J'ai jamais dit le contraire mais soit il s'exprime mal soit il a déjà la solution  [:spamafote]  


 
visiblement, ce qu'il veut, c'est un mécanisme comme les références en C++, mais c'est pas dispo en C, désolé ...
 
Edit : A la limite, ca peut se faire via une macro, dans ce cas .... (pas taper, Taz ! :ange:)


Message édité par theshockwave le 08-08-2003 à 19:56:38

---------------
last.fm
n°481624
neo9205
Posté le 08-08-2003 à 21:35:49  profilanswer
 

theShOcKwAvE a écrit :


 
visiblement, ce qu'il veut, c'est un mécanisme comme les références en C++, mais c'est pas dispo en C, désolé ...
 
Edit : A la limite, ca peut se faire via une macro, dans ce cas .... (pas taper, Taz ! :ange:)


 
Oui apparement c'est pas possible comme je veux.par contre en C++ ça marchera ce que je veux il semble.

mood
Publicité
Posté le 08-08-2003 à 21:35:49  profilanswer
 

n°481630
Lalorette
Posté le 08-08-2003 à 21:37:37  profilanswer
 

en C t'as pas le choix.
Les pointeurs c'est plus propre que les références de C++. Pk ?
Tout simplement parce que çà oblige a réfléchir a ce qu'on fait et a comprendre comment la machine fonctionne.
C'est donc une très bonne chose.
 
Car à force de les mépriser on arrive avec énormément de personnes qui se disent programmeur, et qui ne maitrisent pas cette notion pourtant essentielle de la prog.

n°481641
Taz
bisounours-codeur
Posté le 08-08-2003 à 21:39:54  profilanswer
 

Lalorette a écrit :

en C t'as pas le choix.
Les pointeurs c'est plus propre que les références de C++. Pk ?
Tout simplement parce que çà oblige a réfléchir a ce qu'on fait et a comprendre comment la machine fonctionne.
C'est donc une très bonne chose.
 
Car à force de les mépriser on arrive avec énormément de personnes qui se disent programmeur, et qui ne maitrisent pas cette notion pourtant essentielle de la prog.

je vois pas en quoi c'est plus propre...

n°481866
ACut
Posté le 09-08-2003 à 00:06:06  profilanswer
 

En C, TOUS les arguments de fonctions sont passés par valeur, même si ce sont des arguments de type pointeur.
 
Ainsi, quand tu écris:
 
 void swap(int *x,int *y) // passage des parametres par adresse
 
en fait ton commentaire est légèrement erroné, car la fonction swap(...) ne fait que recevoir des VALEURS qui se trouvent être de type int* (pointeurs d'entier).
 
Que fait ta fonction swap()? Elle s'alloue LOCALEMENT -- j'insiste sur ce terme! -- deux variables x et y de type int*, lesquelles variables reçoivent des valeurs fournies par l'appelant.
 
Pour simplifier, disons que dans main() tu as:
 
 int  A;  // déclare et alloue A de type int
 int  B;  // déclare et alloue B de type int
 
 int* pA; // déclare et alloue pA de type int*
 int* pB; // déclare et alloue pB de type int*
 
 pA = &A; // charge dans pA l'adr de A
 pB = &B; // charge dans pB l'adr de B
 
[je garderai ces notations par la suite]
 
Lorsque tu fais swap(pA, pB), il se passe implicitement et localement, compte tenu du prototype de la fonction:
 
 int* x; // déclare/alloue localement x de type int*
 int* y; // déclare/alloue localement y de type int*
 x = pA; // charge dans x la VALEUR de pA
         // (en l'occurrence l'adr de A = &A)
 y = pB; // charge dans y la VALEUR de pB
         // (en l'occurrence l'adr de B = &B)
 
A partir de là, toutes les opérations que tu vas faire DIRECTEMENT sur x ou sur y, du genre:
 
<<
...
x=y;
y=temp;
...
>>
 
se bornent à permuter, non pas des "adresses" au sens où tu l'entends, mais simplement des valeurs temporaires de variables locales.
 
A l'issue de ce bout de code, compte tenu du contexte, x contient effectivement l'adresse de B et y l'adr de A (puisque x et y ont échangé leurs valeurs, initialisées sur pA et pB), MAIS aucune des variables A, B, pA, pB n'ont changé de valeur!
 
Donc, il ne faut pas s'étonner si, revenant dans le main(), tout est comme avant.
 
Quand tu écris que tout se passe bien dans le swap, c'est d'ailleurs un trompe-l'oeil, vu ton code de test:
 
<<
printf("adresse de x: %x ,adresse de y: %x\n",x,y);
printf("contenu de x: %d ,contenu de y: %d\n",*x,*y);
>>
 
Ce test est inexact car:
- l'ADRESSE d'une variable X n'est pas "X" mais "&X"
- le CONTENU d'une variable X n'est pas "*X" mais "X" (!)
- l'écriture "*X" représente le contenu (évalué selon le typage du pointeur) situé à l'adresse contenue dans X
 
Ta question initiale était:
 
<< De retour dans le main, "a" et "b" ne sont pas permutés! Mais pourquoi alors que j'ai transmis a et b par leurs adresses >>
 
La réponse est que tu n'as pas TRANSMIS a et b par leurs adresses, tu as chargé dans x et y locales des valeurs qui se trouvent être les adresses de a et b ...mais sans jamais manipuler le contenu de ces adresses.
 
La seule manière de le faire était évidemment de passer par *x et *y. Je ne comprends pas ta "contrainte" t'imposant d'<<échanger par adresse dans swap() et non par contenu de pointeur>>. Au demeurant, cette formule n'est pas claire du tout. Le mécanisme des pointeurs te permet de modifier dans une fonction la valeur d'une variable qui lui est externe mais dont elle connaît l'adresse, pourquoi voudrais-tu te priver de cette fonctionnalité intrinsèque du C?
 
Le C++ a introduit le passage d'argument par référence, càd réellement "par adresse" au sens où tu l'entends. C'est essentiellement une amélioration syntaxique, puisque ça permet de prototyper swap(int& x, int& b) et d'appeler swap(A,B) pour manipuler -- dans swap! -- directement les variables-arguments (et non des recopies de leur valeur).
 
Mais, dans tous les cas de figure, il est peut-être utile de rappeler qu'étant donné une variable X de type qcq, l'adresse de X (&X) n'est pas accessible EN ECRITURE. Tu peux faire en sorte qu'un pointeur pX pointe sur &Y au lieu de pointer sur &X, tu peux modifier la valeur de X indirectement via un pointeur (opérateur *), mais aucun code ne te permet de "réadresser" X. Donc, si ton objectif était d'échanger les adresses de A et de B... c'est voué à l'échec.
 
Pour aller + loin, il ne serait pas superflu que tu nous précises exactement le cahier des charges de ta fonction swap(). Au fond, quelles valeurs doit-elle échanger:
1 - celles de A et B seulement ?
2 - celles de pA et pB seulement ?
3 - celles de A et B ET de pA et pB ?
 
Dans les cas 2 et 3, il sera nécessaire de fournir à swap les adresses de pA et pB, ce qui force à prototyper:
 
 swap(int** X, int** Y)
 
et à appeler la fonction avec un swap(&pA, &pB)
 
Dans le cas 3, le code pourrait être du genre:
 
 void swap(int** X, int** Y)
 // Contexte extérieur:
 //  int A ; int B ; int* pA=&A ; int* pB=&B;
 // Objectifs:
 //  échanger les val de A et B  ET  les val de pA et pB
 // Situation initiale implicite:
 //  X = &pA  |  *X = pA  -  **X = *pA = A
 //  Y = &pB  |  *Y = pB  -  **Y = *pB = B
 {
 int  tmp1;  // var tempo pour swapper des INT
 int* tmp2;  // var tempo pour swapper des INT*
 
 // échanger les valeurs de A et B
 tmp1 = **X;  // sauvegarder la valeur de A
 **X = **Y;   // charger dans A la valeur de B
 **Y = tmp1;  // charger dans B la valeur sauvergardée
 
 // A ce stade, les var externes A et B
 // ont leurs valeurs permutées, mais on
 // a encore: pA=&A et pB=&B
 // et, bien sûr, X=&pA et Y=&pB
 
 // échanger les valeurs de pA et pB
 tmp2 = *X;  // sauvegarder la valeur de pA(=&A)
 *X = *Y;    // charger dans pA la valeur de pB(=&B)
 *Y = tmp2;  // charger dans pB la valeur sauvergardée
 
 // A ce stade, d'une part les var externes A et B
 // ont leurs valeurs permutées, d'autre part
 // pA=&B et pB=&A (v. commentaire infra)
 
 }
 
Observons pour en finir que cette double permutation a pour conséquence que:
- pA pointe sur B qui a pris la valeur initiale de A
- pB pointe sur A qui a pris la valeur initiale de B
 
Donc, si on note a la valeur init. de A et b la valeur init. de B avant l'appel de swap, on a en sortie:
 
 A = b  , B = a
 pA = &B  , pB = &A
 *pA = a  , *pB = b (!)
 
Ce n'était probablement pas l'objectif poursuivi, mais je crois que l'exercice avait valeur pédagogique... Non?


Message édité par ACut le 09-08-2003 à 00:22:10
n°481870
Taz
bisounours-codeur
Posté le 09-08-2003 à 00:15:42  profilanswer
 

ben fais un edit

n°481875
ACut
Posté le 09-08-2003 à 00:27:28  profilanswer
 

Merci, Taz. J'avais pas encore trop le réflexe...

n°481985
neo9205
Posté le 09-08-2003 à 13:02:50  profilanswer
 

ACut a écrit :

En C, TOUS les arguments de fonctions sont passés par valeur, même si ce sont des arguments de type pointeur.
 
Ainsi, quand tu écris...
 


Extra ta réponse, c'est exactement ce que je cherchais à comprendre.Je voulais vraiment exploiter à fond les pointeurs et les comprendre dans les moindres détails et là ça va beaucoup mieux avec ton explication.
 
En fait, je voulais tenter d'échanger les valeurs de a et b via leur adresses respectives.De cette manière, a aurait la valeur de b et b la valeur de a tout ceci via la fonction swap().
En tout cas merci pour ton explication  :hello:


Message édité par neo9205 le 09-08-2003 à 13:47:11
n°481987
Taz
bisounours-codeur
Posté le 09-08-2003 à 13:07:53  profilanswer
 

meme remarque pour toi neo: pas la peine de citer 15 pages surtout si la citation ne te sers à rien

n°482460
ACut
Posté le 10-08-2003 à 14:35:29  profilanswer
 

De rien, j'ai pris plaisir à y réfléchir.

n°482475
neo9205
Posté le 10-08-2003 à 14:51:34  profilanswer
 

ACut a écrit :


 A = b  , B = a
 pA = &B  , pB = &A
 *pA = a  , *pB = b (!)


 
Ah non je me suis emballé trop vite face à ta réponse...En fait, tu as une petite erreur :
 
*pA=b puisque pA pointe sur b (pA=&B)
*pB=a puisque pB pointe sur a (pB=&A)

n°482580
ACut
Posté le 10-08-2003 à 17:18:58  profilanswer
 

Non, pas d'accord avec toi, je ne vois pas mon erreur. Tu écris:
 
<<
*pA=b puisque pA pointe sur b (pA=&B)
*pB=a puisque pB pointe sur a (pB=&A)
>>
 
Or:
 
pA = &B   // pA = adresse de la variable "B"
 
  donc
 
*pA = (valeur de la variable "B" )
      // et non pas "pA pointe sur b"
 
  or
 
B vaut a  (à ce stade du process, puisque permutation avant)
 
 donc :
 
*pA = a  // ce qui ne veut pas dire:
         // *pA = valeur de "A" actuelle
         // mais:
         // *pA = valeur initiale de "A"
 
 


Message édité par ACut le 10-08-2003 à 17:26:34
n°482581
Taz
bisounours-codeur
Posté le 10-08-2003 à 17:19:48  profilanswer
 

ACut a écrit :

Je suis banni du forum (TT), donc je pense que je ne pourrais pas te répondre, mais je crois que tu te plantes...

:heink:

n°482591
ACut
Posté le 10-08-2003 à 17:34:09  profilanswer
 

Ouah!
 
Je savais pas qu'être censuré sur une branche laissait la possibilité de s'exprimer sur les autres branches!
 
Taz, tu vas pas me zigouiller toi aussi? Ton camarade krapaud m'a adressé le mail suivant:
 
<<comportement infantile, niaiserie à propos du p2p>>
 
qui me vaut d'être évincé de Software&Réseau
 
Je n'ai donc pas pu répondre aux attaques de ces intellectuels. Dommage, mes arguments étaient pondérés je crois...
 
Bref, fin de digression

n°486810
Krapaud
Posté le 14-08-2003 à 09:33:12  profilanswer
 

... tu vas couiner longtemps comme ça?

n°486831
ACut
Posté le 14-08-2003 à 09:45:49  profilanswer
 

Retourne dans ton Reich, craporal. Tu vois pas qu'ici les gens ont un cerveau?


---------------
NOUVEAU! Le guide de l'édition en version ebook : http://marcautret.free.fr/autret/150q-ebook/
n°486835
Taz
bisounours-codeur
Posté le 14-08-2003 à 09:47:33  profilanswer
 

halte au feu. ici, c'est moi qui commande.

n°486839
antp
Super Administrateur
Champion des excuses bidons
Posté le 14-08-2003 à 09:54:26  profilanswer
 

ACut a écrit :

Retourne dans ton Reich, craporal. Tu vois pas qu'ici les gens ont un cerveau?


 
heu t'es sûr que tu veux continuer à pouvoir poster ici ?


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
mood
Publicité
Posté le   profilanswer
 


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

  probleme pour permutter 2 entiers par adresse...

 

Sujets relatifs
petit probleme sur liste chainée simpleProbleme d'implementation operator= en C++
[newbies en PHP] problème de base (mais qui m'énerve!)[ASP/SQL] problème insert into......
Problème de serveur SMTP pour envoi de mail en phpOpera - Probleme
[HTML / CSS] Problème avec le "positioning"[Perl] Probleme de formulaire en post
problème avec la balise FRAMESET (laisser un menu constament affiché)probleme graphique
Plus de sujets relatifs à : probleme pour permutter 2 entiers par adresse...


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