Les pointeurs : je deviens chèvre !!

Les pointeurs : je deviens chèvre !! - C - Programmation

Marsh Posté le 10-01-2013 à 18:47:03    

Bonsoir,
 
je patauge depuis hier avec ce code qui est destinné à tourner sur un microcontrolleur. Et je ne suis pas sûr si cela est une erreur de codification (fortement probable compte tenu des difficultés que j'ai avec les pointeurs et les tableaux  :o ) ou un problème d'environnement de développement (MPLAB IDE de microchip). Voici le code en question :

Code :
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. using namespace std;
  6. typedef struct {
  7.     char *Rx_buffer; // RX buffer
  8. } RS_232;
  9. RS_232 Polarimetre;
  10. char UART5_Buffer_Rx[32];
  11. unsigned char MesurerRotation(char * cBuffer) {
  12.     char tem[15] = "je suis labas";
  13.     char *jj;
  14.     char i;
  15.     Polarimetre.Rx_buffer = &UART5_Buffer_Rx[0];
  16.     jj = &UART5_Buffer_Rx[0];;
  17.     for (i = 0; i < 15; i++)
  18.         UART5_Buffer_Rx[i] = tem[i];
  19.     cBuffer = Polarimetre.Rx_buffer;
  20.     cBuffer = &UART5_Buffer_Rx[0];
  21.     cBuffer = jj;
  22.     return 1;
  23. }
  24. int
  25. main(void) {
  26.     char Reponse[20] = {0};
  27.     char *Rep2;
  28.     unsigned char I;
  29.     I = MesurerRotation(&Reponse[0]);
  30.  I = MesurerRotation(Rep2);
  31.     return 0;
  32. }


 
Exécuté avec code blocks, je n'ai pas de problème jusqu'à la fin de la fonction MesurerRotation(&Reponse[0]); où la variable cBuffer pointe bien vers UART5_Buffer_Rx[0].
 
Mais lors du retour dans le main(), la valeur du pointeur est perdue. Et ceci de la même façon pour le deuxième appelle (ce qui est assez logique).
 
mais je ne comprends pas ce qui cloche... c'est probablement ce qui explique le comportement de la fonction MesurerRotation lorsque je l’exécute avec MPLAB : cBuffer ne change pas de valeur lors de l’exécution des lignes  

  •   cBuffer = Polarimetre.Rx_buffer;
  •   cBuffer = &UART5_Buffer_Rx[0];
  •   cBuffer = jj;


Bref, je deviens vert, rouge....  
 
Toute aide sera plus que la bien venue !
Jean-Marie

Message cité 1 fois
Message édité par schneiderj le 10-01-2013 à 20:19:28
Reply

Marsh Posté le 10-01-2013 à 18:47:03   

Reply

Marsh Posté le 10-01-2013 à 19:07:23    

Edit : fausse manipulation qui fait que j'ai validé 2 fois :(


Message édité par Farian le 10-01-2013 à 19:10:28
Reply

Marsh Posté le 10-01-2013 à 19:09:55    

Bonsoir !
 
Je ne comprends pas bien votre code ...
 
A quoi sert le paramètre cBuffer dans la fonction MesurerRotation, puisqu'il n'est jamais utilisé ?
 
Dans ma compréhension, la fonction MesurerRotation remplit le tableau UART5_Buffer_Rx à partir de la chaîne "je suis labas" et modifie la structure Polarimetre.
 
Si les lignes ci-dessous, auxquelles vous faites référence ...
 
      cBuffer = Polarimetre.Rx_buffer;
      cBuffer = &UART5_Buffer_Rx[0];
      cBuffer = jj;  
 
sont placées dans la fonction "MesurerRotation", le comportement que vous évoquez est normal : dans la fonction, la variable "cBuffer" est modifiée par ces lignes, mais la variable qui a été passée à la fonction, elle, n'est pas modifiée (un paramètre toujours passé par valeur en C).
 
Si vous voulez modifier cette valeur, vous devez passer un "char **", un peu comme-ci :
 

Code :
  1. unsigned char MesurerRotation(char **cBuffer)
  2. {
  3.     ...
  4.     *cBuffer = UART5_Buffer_Rx; /* équivalent à &UART5_Buffer_Rx[0];
  5.     ...
  6. }


 
et modifier le main
 

Code :
  1. ...
  2. char *Rep2;
  3. unsigned char I;
  4. I = MesurerRotation(&Rep2);
  5. ...


 
 
 
 

Reply

Marsh Posté le 10-01-2013 à 20:15:39    

Merci Farian pour cette réponse !
 
Je vais tester cela est chercher de la documentation et essayer de comprendre ce mécanisme.  
cBuffer n'est pas utilisé dans la fonction, mais me permet de récuperer la valeur lue par cette fonction. La valeur renvoyé par la fonction me sert qu'en à elle de savoir si j'ai une valeur enregistrée par cBuffer.
 
Jean-Marie

Reply

Marsh Posté le 10-01-2013 à 20:57:53    

(Vous avez modifié le code, car je ne comprenais plus rien :) )
 
L'idée est simple, le paramètre que vous passez peut être modifié dans la fonction mais les modifications seront perdues au retour de la fonction.
 
En revanche, si vous passez un pointeur (ou un tableau, ou l'adresse d'une structure), vous pouvez modifier la valeur sur laquelle pointe le paramètre (ou modifier une (ou plusieurs) valeur(s) du tableau ou un (ou plusieurs) champ(s) de la structure ).  
 
C'est ce mécanisme que j'exploite dans mon exemple en passant un pointeur sur une valeur à modifier (qui est elle-même un pointeur sur un char, d'où le double pointeur).
 

Reply

Marsh Posté le 14-01-2013 à 18:47:57    

schneiderj a écrit :


Code :
  1. unsigned char MesurerRotation(char * cBuffer) {
  2.     ...
  3.     cBuffer = Polarimetre.Rx_buffer;
  4.     cBuffer = &UART5_Buffer_Rx[0];
  5.     cBuffer = jj;
  6.     return 1;
  7. }


 
mais je ne comprends pas ce qui cloche... c'est probablement ce qui explique le comportement de la fonction MesurerRotation lorsque je l’exécute avec MPLAB : cBuffer ne change pas de valeur lors de l’exécution des lignes  

  •   cBuffer = Polarimetre.Rx_buffer;
  •   cBuffer = &UART5_Buffer_Rx[0];
  •   cBuffer = jj;


Bref, je deviens vert, rouge....  
 
Toute aide sera plus que la bien venue !
Jean-Marie


Bonsoir
C'est exactement le même problème qu'avec le code simplifié suivant

Code :
  1. void fct(int i)
  2. {
  3.     i=10;
  4. }
  5. int main(void)
  6. {
  7.     i=5;
  8.     fct(i);
  9. }


La variable i de fct n'est qu'une copie de la variable i du main. Et donc la modif dans la fonction est perdue. Dans votre code, le cBuffer de la fonction ne reçoit qu'une copie de l'adresse envoyée par le main. Cette copie est bien modifiée mais perdue en fin de fonction.
Si vous voulez modifier le buffer d'origine, il faut utiliser l'adresse (copiée certes mais c'est la copie de l'adresse d'une vraie variable) et aller donc taper dans la zone pointée par cette adresse...
 

Code :
  1. unsigned char MesurerRotation(char * cBuffer) {
  2.     ...
  3.     /* Sous réserve que les valeurs de droite soient bien adaptées à l'endroit où elles sont copiées */
  4.     *cBuffer = Polarimetre.Rx_buffer;         
  5.     // ou cBuffer[0]=Polarimetre.Rx_buffer;
  6.     *(cBuffer+1) = &UART5_Buffer_Rx[0];
  7.     // ou cBuffer[1] = &UART5_Buffer_Rx[0];
  8.    *(cBuffer+2) = jj;
  9.    // ou cBuffer[2]=jj;
  10.     return 1;
  11. }


Message édité par Sve@r le 14-01-2013 à 18:49:30

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

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