IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Parité d'une variable


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut Parité d'une variable
    Bonjour.
    J'ai ce bout de code qui est sensé vérifier si une variable est paire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
      m_State=0;
      }
     
      void Loop(){
     
        if (m_State++ & 1){
           digitalWrite(kOutPinAssyBlink,HIGH);
           m_CurCounter=50;                       // Here we force the next call to a shorter value
        }
        else {
          digitalWrite(kOutPinAssyBlink,LOW);
        }
      }
     
      unsigned char m_State;    // State counter, short pulse if Odd
    Le morceau de code ci dessus est issus du code complet en fin de post.
    Je n'arrive pas à comprendre comment fonctionne ce code.
    J'ai tenté de "bricoler avec la variable m_State pour la faire afficher à différente étape d'une boucle itérative, mais je ne vois rien qui puisse m’éclairer.

    Ci après, mon bricolage sur la variable m_State :
    J'imagine que (m_State++ & 1) doit renvoyer quelque chose, mais je ne sais comment faire pour me montrer cette valeur de retour.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    #include <iostream>
    using namespace std;
    int main()
    {
        cout << "Hello !\n\n";
        for (int i = 0; i < 3; i++)
        {
            static unsigned char m_State = 0; // State counter, short pulse if Od
            cout << "\nvar =  " << m_State<< endl;
            (m_State++ & 1) ? cout << "\nm_State++ & 1 = " : cout << "\nrien";
            cout << "\nvar =  " << m_State;
        }
        return 0;
    }
    Code complet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    /*
    Cath Copyright Cyrob 2021
    Cyrob Arduino Task helper by Philippe Demerliac
    See my presentation video in French : https://youtu.be/aGwHYCcQ3Io
    See also for v1.3 : https://youtu.be/ph57EpJPs5E
    =====================================================================================
    ==========================   OPEN SOURCE LICENCE   ==================================
    =====================================================================================
    Copyright 2021 Philippe Demerliac Cyrob.org
    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
    OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    ................................................................................................................
    Release history
    ................................................................................................................
    Version Date        Author    Comment
    1.0     30/08/2021  Phildem   First version tested ok
    1.1     05/09/2021  Phildem   Misc fixes, better comments and presentation
    1.2     06/09/2021  Phildem   Remove unnecessary Cath:: in Cath class definition, (Warning removed)
    1.3     08/09/2021  Phildem   Misc comments/name fixes, Memory optimised, __CathOpt_SmallCounter__ option added
    1.4     13/09/2021  Soif      Fixes english comments & indentation
    */
     
     
    //____________________________________________________________________________________________________________
    // Start of Cath definition__________________________________________________________________________________
     
    #define kMaxCathTask    9         // Max Number of task instances. MUST BE >= to tasks instancied
     
    #define __CathOpt_SmallCounter__  // Comment this line to allow 32 bit delay. If not, max period is 65536 ms
     
    #ifdef __CathOpt_SmallCounter__
    typedef uint16_t CathCnt;
    #else
    typedef uint32_t CathCnt;
    #endif
     
     
    class Cath{
     
      public:
     
    // Derived class MUST implement these 2 methods
      virtual void          SetUp() =0;                 // Called at setup
      virtual void          Loop()  =0;                 // Called periodically
     
      CathCnt               m_CurCounter;               // Curent number of ms before next Loop call
      CathCnt               m_LoopDelay;                // Default period of Loop call (in ms)
     
      static uint8_t        S_NbTask;                   // Actual number of task instances
      static Cath*          S_CathTasks[kMaxCathTask];  // Array of task object pointers
      static uint8_t        S_LastMilli;                // Used to call every ms (a byte is enought to detect change)
     
      //..............................................................
      // Must be called in task constructors to register in the task list
      // WARNING : think to set kMaxCathTask as needed
      // Task   : Pointer to the derivated task to register
      // Period : Loop call Period (in ms). WARNING do not pass 0!
      // Offset : Delay of the first call in ms (1 def). WARNING do not pass 0!
      static void S_Register(Cath* Task,CathCnt Period,CathCnt Offset=1){
        Task->m_LoopDelay=Period;
        Task->m_CurCounter= Offset;
        Cath::S_CathTasks[Cath::S_NbTask++]=Task;
      }
     
      //..............................................................
      // Must be called once in Arduino setup to call all the task setups
      static void S_SetUp(){
        for(int T=0;T<S_NbTask;T++)
          Cath::S_CathTasks[T]->SetUp();
      }
     
       //..............................................................
      // Must be called once in Arduino Loop to call all the task loop if needed
      static void S_Loop(){
        uint8_t CurMilli=millis();
        if (CurMilli!=S_LastMilli) {
          S_LastMilli=CurMilli;
          for(int T=0;T<S_NbTask;T++) 
            if ( Cath::S_CathTasks[T]->m_CurCounter--==0) {
              Cath::S_CathTasks[T]->m_CurCounter=Cath::S_CathTasks[T]->m_LoopDelay;
              Cath::S_CathTasks[T]->Loop();
            }
         }
      }
     
    };
     
    //Cath static variables definitions 
    //(Note set to 0 for code clarity but done by default anyway because they are static)
    uint8_t       Cath::S_NbTask=0;
    Cath*         Cath::S_CathTasks[kMaxCathTask];
    uint8_t       Cath::S_LastMilli=0;
     
    // End of Cath definition ___________________________________________________________________________________
    //___________________________________________________________________________________________________________
     
     
     
     
    //****************************************************************************************************************
    // I/O Abstraction
     
    #define kOutPinSlowBlink  4     // Output pins where different leds are connected
    #define kOutPinFastBlink  5     
    #define kOutPinAssyBlink  6
    #define kOutPinAorB       7
    #define kOutPinAandB      8
    #define kOutPinAxorB      9
     
    #define kInPinA           2     // Input pins where pushbuttons are connected (Internal pullup required)
    #define kInPinB           3
     
     
    //****************************************************************************************************************
    // Globals
     
    bool gPushA=false;      // Memory state of button A, true if pushed, debounced
    bool gPushB=false;      // Memory state of button B, true if pushed, debounced
     
    //Exemple task ...........................................................................................
     
    //Blinker ..........................................................................................
    class Blinker: public Cath{
     
      public:
     
      Blinker(uint8_t Pin,unsigned long Period,unsigned long Offset=1){
        m_Pin=Pin;
        Cath::S_Register(this,Period,Offset);
      }
     
      void SetUp(){
        pinMode(m_Pin,OUTPUT);
        digitalWrite(m_Pin, LOW);
      }
     
      void Loop(){
        digitalWrite(m_Pin,!digitalRead(m_Pin));
      }
     
      uint8_t     m_Pin;    // Number id of the output pin to blink
    };
     
    //Assy Blinker ..........................................................................................
    class ABlinker: public Cath{
     
      public:
     
      ABlinker(){
        Cath::S_Register(this,2000,666);
      }
     
      void SetUp(){
        pinMode(kOutPinAssyBlink,OUTPUT);
        digitalWrite(kOutPinAssyBlink, LOW);
        m_State=0;
      }
     
      void Loop(){
     
        if (m_State++ & 1){
           digitalWrite(kOutPinAssyBlink,HIGH);
           m_CurCounter=50;                       // Here we force the next call to a shorter value
        }
        else {
          digitalWrite(kOutPinAssyBlink,LOW);
        }
      }
     
      unsigned char m_State;    // State counter, short pulse if Odd
    };
     
    //PushBut ..........................................................................................
    class PushBut: public Cath{
     
      public:
     
      PushBut(uint8_t Pin, bool* Store){
        m_Pin=Pin;
        m_Store=Store;
        Cath::S_Register(this,20);    // Here 20ms is for switch deboudcing
      }
     
      void SetUp(){
        pinMode(m_Pin,INPUT_PULLUP);
      }
     
      void Loop(){
        *m_Store=!digitalRead(m_Pin); // We invert the value because the switch in inverted (connected to ground)
      }
     
        uint8_t     m_Pin;      // Number Id of input Pin to test
        bool*       m_Store;    // Boolean value to store the result
    };
     
    //PinAorB ..........................................................................................
    class PinAorB: public Cath{
     
      public:
     
      PinAorB(){
        Cath::S_Register(this,20);
      }
     
      void SetUp(){
        pinMode(kOutPinAorB,OUTPUT);
      }
     
      void Loop(){
        digitalWrite(kOutPinAorB, gPushA || gPushB);
      }
    };
     
    //PinAandB ..........................................................................................
    class PinAandB: public Cath{
     
      public:
     
      PinAandB(){
        Cath::S_Register(this,20);
      }
     
      void SetUp(){
        pinMode(kOutPinAandB,OUTPUT);
      }
     
      void Loop(){
        digitalWrite(kOutPinAandB, gPushA && gPushB);
      }
    };
     
    //PinAxorB ..........................................................................................
    class PinAxorB: public Cath{
     
      public:
     
      PinAxorB(){
        Cath::S_Register(this,60);
      }
     
      void SetUp(){
        pinMode(kOutPinAxorB,OUTPUT);
      }
     
      void Loop(){
        digitalWrite(kOutPinAxorB, !gPushA != !gPushB && !digitalRead(kOutPinAxorB));
      }
    };
     
    //****************************************************************************************************************
    // Global tasks instanciation
     
    // 3 Instances of the blinker task
    Blinker   BuiltIn(LED_BUILTIN,100,50);
    Blinker   Blinker1(kOutPinSlowBlink,500);
    Blinker   Blinker2(kOutPinFastBlink,1500,500);
     
    // 2 Instances of the PushBut task
    PushBut   PushA(kInPinA,&gPushA);
    PushBut   PushB(kInPinB,&gPushB);
     
    // 1 instance by tasks for these one
    ABlinker  Assy;
    PinAorB   AorB;
    PinAandB  AandB;
    PinAxorB  AxorB;
     
     
    //-----------------------------------------------------------------------------------------------------------------
    void setup() {
      Cath::S_SetUp();    // Just ask Cath to call the task's setup
    }
     
    //-----------------------------------------------------------------------------------------------------------------
    void loop() {
      Cath::S_Loop();    // Just ask Cath to call the task's loop
    }

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Ça n'est pas en récupérant des morceaux de code sur le net que l'on construit son code.

    On sait qu'un nombre est pair si en le divisant par 2 on obtient un reste nul. Ça s'écrit donc if ( x % 2 == 0 ). Il y a en effet quelque part dans l'extrait fourni quelque chose de similaire, c'est juste un peu plus compliqué.

    Et si tu souhaites savoir ce que vaut (m_State++ & 1), rien ne t'empêches d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::cout << (m_State++ & 1) << '\n';
    std::cout << (m_State++ & 1) << '\n';
    std::cout << (m_State++ & 1) << '\n';
    Tu verras que ça change un peu d'avis!

  3. #3
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Mais pourquoi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    int main()
    {
        char m_State = 1;
        std::cout << m_State << '\n';
     
        return 0;
    }
    ne m'affiche rien ?

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 770
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 770
    Par défaut
    Citation Envoyé par hary66 Voir le message
    Mais pourquoi : ne m'affiche rien ?
    parce que tu n'as pas pigé la différence entre le code ASCII 1 ("start of heading") et le caractère '1' (code ASCII 49)
    char peut être utilisé pour 1 plage de nombre limité : 0 -> 255, -127 -> 127 (<- il me semble ).
    En C/ printf, on rajoute le caractère '0' pour l'afficher. En C++/ cout, il faut caster.

    En C/ C++, tu as 1 différence entre simple quotes '' et double quotes ""

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par hary66 Voir le message
    Mais pourquoi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    int main()
    {
        char m_State = 1;
        std::cout << m_State << '\n';
     
        return 0;
    }
    ne m'affiche rien ?
    C'est normal, car tu as définis m_Statte comme étant de type char.

    Or, std::cout considère "implicitement" que ce que l'on veut afficher est en fait le "symbole", le "glyphe" correspondant à l'indice de notre char dans la table ASCII.

    "Manque de bol", il n'y a aucun symbole "visuel", aucun "glyphe" correspondant caractère se trouvant à l'indice 1 de la table ASCII qui correspond normalement à l'instruction SOH (Start Of Heading).

    Si tu veux afficher une valeur numérique, il faut donc
    • soit que tu utilise n'importe quel autre type primitif spécifiquement prévu pour représenter une valeur numérique entière (short, int, long, long long, dans leurs version signées ou non signée)
    • soit que tu "transtype" ("convertisse") ta donnée de type char en une donnée dont le type serait un des types spécifiquement prévu pour représenter une valeur numérique entière


    Ton code "corrigé" devrait donc prendre une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    int main()
    {
        /* unsigned */ int m_State = 1; // ou short, ou long, ou même long long
        std::cout << m_State << '\n';
     
        return 0;
    }
    ou, éventuellement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    int main()
    {
        char m_State = 1;
        std::cout << static_cast< /*unsigned*/ int>(m_State) << '\n'; // ou short, ou long, ou même long long
     
        return 0;
    }

    Notes au passage qu'il existe un règle en C++ par laquelle toutes les données écrites en mémoire dans un même contexte doivent être "alignées" de telle manière que le premier byte (le premier octet, si tu préfères) de chaque donnée se trouve à une adresse mémoire qui soit un multiple de la taille de la donnée la plus grande, et qui soit également un exposant de 2 (autrement dit: 2, 4, 8 ou 16).

    Si bien que tu n'as que très peu de situations dans lesquelles tu aurait un véritable intérêt à représenter une valeur entière sous la forme d'un /* unsigned*/ char, même si la valeur numérique maximale que tu voudrais être en mesure de représenter était dans les limites admises pour ce type (dans l'intervalle [-127, 127[ pour la version "signed", dans l'intervale [0, 255[ pour la version "unsigned").

    Il y aurait en effet -- à l'exception de quelques situations très particulières -- très souvent un "padding", un alignement des données qui serait effectué de telle manière à ce que le premier byte de chaque donnée respecte cette règle.

    Ainsi, si tu avais un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(){
         char a = 1; // sizeof(char) = 1
         int i = 153634 ; // sizeof(int) = 4
         /* la suite du code */
    }
    les données seraient de toutes manières représentées en mémoire sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    emplacement des premiers
    bytes des données (tous les 4 bytes, correspondant à la taille d'un int)
            |
    +-------+-------+
    |-|-|-|-|-|-|-|-| -->espace mémoire utilisé (8 bytes au total)
    | |     |       |
    | |     |-|-|-|-| -->espace requis pour un int (4 bytes)
    | |     |
    | |-|-|-| --> alignement ( 3 bytes "perdus")
    | |
    |-| --> espace requis pour un char (1 byte)
    (chaque espace représenté par |-| correspond à un byte ou à un octet)
    NOTA: j'ai considéré dans cet exemple que sizeof(int) était égal à 4. Il s'agit d'une "bonne base" pour l'explication, cependant cette valeur dépend d'énormément de choses, et n'est donc pas ** forcément ** celle que tu pourrais retrouver sur ton système particulier .
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre confirmé
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Juin 2014
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable de compte

    Informations forums :
    Inscription : Juin 2014
    Messages : 219
    Par défaut
    Je pense que je comprends un peu mieux.

    Le code où j'ai récupéré ça est pour un microcontroleur, et l agars à sans doute souhaité optimiser : Je ne sais pas si il y a cette histoire de padding avec les microcontroleurs, auquel cas on peut comprendre la démarche peut être.

  7. #7
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    Il n'y a pas de padding sur microcontroleurs (ça dépend lesquels mais sur arduino /Avr Atmel , non ).

Discussions similaires

  1. Demande d'aide à la compréhension du fonctionnement d'un fichier Excel
    Par Akkatsuki dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 29/06/2016, 15h16
  2. Aide à la compréhension de code
    Par Yakuzan dans le forum Débuter
    Réponses: 1
    Dernier message: 30/03/2010, 21h58
  3. Demande d'aide sur mon code
    Par b.soufiane dans le forum C++
    Réponses: 6
    Dernier message: 07/12/2007, 16h36
  4. Demande d'aide pour un problème de code source sur devC++
    Par Rickantonais dans le forum Débuter
    Réponses: 28
    Dernier message: 01/08/2007, 14h09
  5. Demande d'aide sur un code source
    Par Soward dans le forum SDL
    Réponses: 3
    Dernier message: 13/06/2007, 20h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo