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 :

Enumération bizarre dans un programme


Sujet :

C++

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut Enumération bizarre dans un programme
    Bonjour,
    Je suis en train de lire le code source d'un programme, et j'ai trouvé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    enum {
    // INCLUDE/mrv/AdMask.h:
    // please repect following mask according to the type
     
     
        ATTR_MASK_INT16     = 0x1000, /* Property flag : INT16 not used in fact */
    C'est pour moi un peu bizarre avec 0X1000, c'est quoi ce type et ça sert à quoi d'énumérer les types comme ça?

    Merci

  2. #2
    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
    Salut,

    La présence de 0x indique au compilateur qu'il doit prendre la valeur sous sa forme hexadécimale, ce qui correspond à la valeur (décimale) de 4096 à la valeur binaire de 1000000000000 (2^12).

    L'idée est de fournrir une valeur explicite pour la valeur énumérée.

    Comme il s'agit d'un masque binaire (comprend: chaque bit de l'énumération représente un flag particulier, non exhaustif) il est souvent plus facile de représenter les valeurs sous forme binaire (ou hexadécimale) que sous forme décimale, car la conversion est plus simple
    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

  3. #3
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    Merci pour ta réponse

  4. #4
    Membre éprouvé

    Profil pro
    activité : oui
    Inscrit en
    Janvier 2014
    Messages
    1 263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : activité : oui

    Informations forums :
    Inscription : Janvier 2014
    Messages : 1 263
    Par défaut
    Bonjour, j'en profite pour réactiver cette discussion.
    Dans les cours de C++, il est décrit qu'une valeur peut être écrite en base 16, 10, 8 (hexadécimal, décimal, octal) ou sous forme de caractère.

    Etant issue du domaine de l'électronique je me demande alors:
    La norme prévoit-elle l'emploi d'un préfixe pour la forme binaire ?
    ... au même titre que 0... ou 0x...
    pourquoi pas 0b... comme le font certains programmes (ex: mikroC for PIC)

    PS: cette forme binaire est indispensable pour donner du sens à la lecture, lorsque l'on travail sur les flag, registre, ou toute valeur dépendant de l'emplacement des bits.

  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 Steinvikel Voir le message
    Bonjour, j'en profite pour réactiver cette discussion.
    Dans les cours de C++, il est décrit qu'une valeur peut être écrite en base 16, 10, 8 (hexadécimal, décimal, octal) ou sous forme de caractère.

    Etant issue du domaine de l'électronique je me demande alors:
    La norme prévoit-elle l'emploi d'un préfixe pour la forme binaire ?
    ... au même titre que 0... ou 0x...
    pourquoi pas 0b... comme le font certains programmes (ex: mikroC for PIC)
    La réponse est simple : non, la norme ne prévoit rien pour indiquer une écriture binaire.

    A vrai dire, cela va même plus loin : il n'y a, à par la possibilité d'avoir une écriture sous la forme des termes true et false, aucune fonction directe permettant de représenter des valeurs binaires.

    Si tu veux l'affichage d'une valeur binaire, tu dois jouer avec des conteneurs spécifiques comme std::bitset (ou boost::dynamic_bitset) qui exposent une fonction susceptible de générer une chaîne de caractères au format binaire.
    PS: cette forme binaire est indispensable pour donner du sens à la lecture, lorsque l'on travail sur les flag, registre, ou toute valeur dépendant de l'emplacement des bits.
    D'un point de vue purement électronique, cela se conçoit sans peine. D'un point de vue purement conceptuel pour la programmation, je subodore que c'est pour orienter les développeurs vers ce qui serait considéré comme une "bonne pratique" : créer une énumération qui reprenne les différentes valeurs pour les flags.

    En simplifiant vraiment beaucoup, on peut considérer qu'il existe deux possibilités de définir une valeur qui ne prend qu'un bit à 1:
    • En retenant la valeur correspondante de chaque bit (1, 2, 4, 8, 16, 32, 64, ...), ce qui n'est quand même pas tellement évident ou
    • en utilisant le décalage de bits : 1<<0 == 1, 1<<1 == 2, 1<<2 == 4, 1<<3==16, ..., ce qui est déjà plus facile, vu qu'il suffit de connaître le "numéro d'ordre" du bit que l'on veut mettre à 1
    (il y a peut être d'autres solutions, mais ce sont en tout état de cause les plus utilisées )

    D'un autre coté, on dispose de toutes manières des opérateurs binaire AND et OR, qui nous permettent de vérifier / définir des flags multiples : 1<<0 |1<<2 vaudra 5 (101 en binaire); FLAGS & N vaudra N si les bits correspondant à la valeur N sont à 1 dans FLAGS.

    Et il ne faut surtout pas oublier que les flags ont systématiquement une signification qui est propre à la mise à 1 du bit correspondant, par exemple, les flags correspondant au formatage d'un texte pour les flux formaté (tels que cout, cin, ifstream ou ofstream) ont (chez moi en tout cas) les valeurs suivante:
    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
     
          boolalpha 	= 1L << 0,  // ==1
          dec 		= 1L << 1,  // ==2
          fixed 		= 1L << 2,  // ==4
          hex 		= 1L << 3,  // ==8
          internal          = 1L << 4,  // ==16
          left 		= 1L << 5,  // ==32
          oct 		= 1L << 6,  // ==64
          right 		= 1L << 7,  // ==128
          scientific 	= 1L << 8,  // ==256
          showbase  	= 1L << 9,  // ==512
          showpoint  	= 1L << 10,  // ==1024
          showpos    	= 1L << 11,  // ==2048
          skipws        	= 1L << 12,  // ==4096
          unitbuf        	= 1L << 13,  // ==8192
          uppercase 	= 1L << 14,  // ==16384
          adjustfield 	= left | right | internal,   // == 32+128 + 16
          basefield 	= dec | oct | hex,         // ==  2 + 8 + 64
          floatfield 	= scientific | fixed,    // == 256 + 4
    (adaptation du flag _Ios_Fmtflags que l'on trouve classiquement dans ios_base.h auxquels j'ai juste ajouté la correspondance en valeur décimale )

    Mon intuition (qui ne demande qu'à être démentie ) est que la norme tend à inciter les développeurs à définir des termes représentant les différents tags qu'ils utilisent, quelle que soit la forme qu'il prennent, en ne fournissant aucun moyen de définir une valeur sous la forme binaire.

    Il est en effet plus facile de comprendre ce que vaut un flag qui correspond à FLAG1 | FLAG3 | FLAG64 que de comprendre le même flag qui serait égal à 1<<1 + 1<<3 +1<<64. D'un point de vue binaire, la représentation est strictement identique, mais, en évitant les "constantes magiques", on gagne en facilité de compréhension Et il en va bien sûr de même lorsqu'il s'agit dévaluer si un bit est à 1 ou non (ou, si tu préfères, si un flag est activé ou non) .

    Après, la forme que prendra la définition des différents flag est laissée à la libre appréciation du développeur. On peut envisager trois solution pour ce faire:
    en utilisant la directive préprocesseur #define:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #define ONE 1<<0
    #define TWO 1<<1
    /* ... */
    #define N 1<<N-1
    En ayant recours au constantes statiques
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    static const int one = 1<<0;
    static const int two = 1<<1;
    /* ... */
    static const int N = 1<<N-1;
    Ou enfin en ayant recours aux énumérations (hein quoi qui a parlé d'énumération fortement typées en C++11 )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    enum /*class */ myEnum{
        one = 1<<0,
        two = 1<<1,
        /* ... */
        n = 1<<n-1
    };
    A titre personnel, je préfères les énumérations en premier recours, puis les constantes statiques. Mais je garde mon argumentaire sur le sujet pour plus tard, s'il t'intéresse
    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 éprouvé

    Profil pro
    activité : oui
    Inscrit en
    Janvier 2014
    Messages
    1 263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : activité : oui

    Informations forums :
    Inscription : Janvier 2014
    Messages : 1 263
    Par défaut
    merci pour cette réactivité, et surtout cette précision

    Ainsi donc, c'est impossible sans bliliothèque...
    Je te suis dans la représentation de chaque flag indépendamment dans la syntaxe. Mais je garde tout de même à l'esprit que chaque domaine a ses avantages et ses inconvénients à l'usage d'une forme ou d'une autre.

    Plus on sera proche du hardware, et plus on aura l'usage de valeurs sous forme de motif (correspondant à l'architecture physique >> électronique), et plus on sera proche du software et plus les valeurs seront abstraites (où la syntaxe apporte tout leur sens).

    Donc si j'ai bien compris, pas d'autre choix que d'écrire quelques lignes supplémentaires avec l'usage de masque ET et OU.
    PS: par expérience de mes débuts, je proscrit l'usage du décalage si se n'est pas dans le but de décaler ^^' (on a vite fait d'expulser 1bit en dehors sens être averti)

    Concernant les énumération, j'ai écrit un post, car je cale sur certaines frontières.
    si le coeur t'en dit... =)

    Savoir pourquoi tu as une préférence pour une enum à plusieurs constantes m'intéresse effectivement, mais je ne sais pas s'il on devrait poursuivre dans cette discussion ou en ouvrir une nouvelle. Dans tout le cas, il me faudra trouver des réponses sur les énumérations pour pouvoir en discuter avec toi.

  7. #7
    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 Steinvikel Voir le message
    Donc si j'ai bien compris, pas d'autre choix que d'écrire quelques lignes supplémentaires avec l'usage de masque ET et OU.
    PS: par expérience de mes débuts, je proscrit l'usage du décalage si se n'est pas dans le but de décaler ^^' (on a vite fait d'expulser 1bit en dehors sens être averti)
    Ce n'est pas faux, mais le risque est quand même particulièrement limité (comparé constantes statiques, par exemple) dans le sens où la norme impose que le type permettant de représenter une valeur énumérée doit au moins permettre la représentation de toutes les valeurs énumérées.

    A priori, rien n'interdirait qu'une énumération proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    enum MyEnum{
       zero   = 1<<0,
       un     = 1<<1, 
       deux   = 1<<2,
       trois  = 1<<3,
       quatre = 1<<4,
       cinq   = 1<<5,
       six    = 1<<6,
       sept   = 1<<7
    };
    soit représentée sous la forme d'un (unsigned) char, bien que, en pratique, ce sera quand même le type (unsigned) int qui sera régulièrement choisi.

    A l'heure actuelle, sans commencer à jouer avec les type uint_XXX, le type numérique entier (non signé) le plus grand dont on dispose est le (unsigned) long long qui est classiquement représenté sous la forme de 64bits. Il est relativement rare (bien qu'il ne soit pas impossible) qu'une énumération ait besoin d'autant de flags
    Plus on sera proche du hardware, et plus on aura l'usage de valeurs sous forme de motif (correspondant à l'architecture physique >> électronique), et plus on sera proche du software et plus les valeurs seront abstraites (où la syntaxe apporte tout leur sens).
    Et encore!

    Adaptions le problème à l’électronique "simple". Je ne sais plus comment cela s'appelle, mais tu te souviens sans doute de ces petits élément qui 7 segments permettant le représentation du chiffre 8 (en plus de tous les autres chiffres et de certaines lettre comme le A, le C ou le E ).

    Si mes souvenirs sont bons, il y avait 8 broches à ces composants : une pour l'alimentation (+1.5volts ) et un pour chaque segment lumineux.

    Qu'est ce qui t'empêcherait d'avoir une énumération qui ressemblerait à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    enum MyEnum{
       horizontalTop = 1<<0,
       horizontalMiddel = 1<<1,
       horizontalBottom = 1<<2,
       verticalTopLeft = 1<<3,
       verticalTopRight = 1<<4,
       verticalBottomLeft = 1<<5,
       verticalBottomRight = 1<<6
    };
    (j'ai été totalement arbitraire dans le choix des valeurs ) et de l'utiliser sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    /* je veux afficher le chiffre 7 : horizontalTop, verticalTopRigth et verticalBottomRight 
     * doivent être allumés
     */
    MyEnum sept = horizontalTop | verticalTopRigth | verticalBottomRight ;
    /* je veux afficher la lettre C : horizontalTop, horizontalBottom, verticalTopLeft et 
     * verticalBottomLeft doivent être allumés
     */
    MyEnum cletter = horizontalTop | horizontalBottom | verticalTopLeft | verticalBottomLeft;
    C'est quand même beaucoup plus clair que toute possibilité qui utiliserait des valeur "magiques" (comprends :dont personne ne sait vraiment d'où elles viennent) pour atteindre le même résultat.

    Et si tu décide (parce que les broches sont classiquement numérotée, et que je n'ai sans doute pas suivi cette numérotation), l'énumération restera correcte, tant que j'utiliserai les bonnes valeurs énumérées : je n'ai absolument pas à m'inquiéter de leur valeur réelle

    Tu as tout à fait raison sur un point : l'informatique n'est qu'un sous ensemble tiré de l’électronique. On y retrouve donc quelques notions similaires (les opérateurs binaires AND et OR qui correspondent aux portes logiques équivalentes, la loi de morgan et d'autres choses intéressantes comme les tables de vérité).

    Mais toute l'évolution des langages de programmation a tendu vers un seul et même objectif : rendre les langages plus proches de celui qu'un humain est susceptible de comprendre (C++ est un langage de troisième génération, après les code binaires et les mnémoniques (assembleur) ) que d'un langage susceptible d'être compris par l'électronique qui chapeaute le tout (en électronique, le seul langage réellement compréhensible est le binaire ).

    Je comprends parfaitement que tu essayes de te "raccrocher aux branches" de ce que tu connais de l'électronique pour aborder le domaine -- qui semble faire partie intégrante de l'électronique -- qu'est le développement informatique. Mais il faut te rendre compte que ce sont deux domaines tout à fait distincts, qui suivent leurs propres règles (même si certaines sont communes) et qui doivent être abordés sous des angles totalement différents : ce n'est pas parce que l'on est un bon électronicien que l'on est un bon développeur, ni inversement
    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

  8. #8
    Membre éprouvé

    Profil pro
    activité : oui
    Inscrit en
    Janvier 2014
    Messages
    1 263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : activité : oui

    Informations forums :
    Inscription : Janvier 2014
    Messages : 1 263
    Par défaut
    je te suis à 100%

    Concernant les exemples, l'afficheur 7 segments (un peu plus gourment qu'une simple pile 1,5V, pour le bas de gamme en tout cas, plutot 3V à 5V, avec un potard pour ajuster), est bien je trouvais ma foi plus simple d'y raccrocher des constante symboliques (ex: #define SEG7_8 0b01111111 ou #define SEG7_8 127) qui correspondent aux bus de l'afficheur, mais forcé de constaté que l'ont finira toujours par rajouter des lignes de "set_bit" qui permettent l'affectation d'une broche physique à son homologue virtuel (une sorte de #define) pour rendre le code plus ou moins portable.
    Pour ce qui concerne les matrices de diode (pas les afficheurs LCD, et bien les ampoules, diodes etc.) ou les chenillards... quelque soit la valeur, c'est plutôt abstrait puisque il est question de dessiner (par l'intermédiaire des diodes éteintes ou allumés), c'est pour ça que dans mes projet j'avais tendance à utiliser des constante symbolique pour les motif qui se répétaient, et des valeurs binaires pour voir le motif dans le code, et pour éviter des erreur de conversion vers une autre base... mais bon, tout ça ne tient plus vraiment la route puisque tout plein d'outils existent pour nous faciliter la vie.
    PS: et puis à l'époque j'avais peut-être pas toutes les bonnes habitudes aussi ^^'

    Ne t'inquiète pas, je suis bien conscient des différences entre le bas niveau et le haut niveau, je ne vois pas tout "en électronique", juste que j'ai un oeil bien plus critique vers cette usage (qui n'est qu'un domaine parmi beaucoup d'autres), je ne gèrerais pas avec la même approche les masques sous-réseaux et les mots de passe.

    PS: RESOLU #2

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Chargement d'une lib partagée C++ dans un programme C
    Par Zero dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 30/09/2003, 16h40
  2. commande shell dans un programme
    Par diefo dans le forum C
    Réponses: 3
    Dernier message: 15/08/2003, 13h37
  3. Réponses: 2
    Dernier message: 24/06/2003, 20h31
  4. [] Utiliser AVI d'une DLL dans mon programme
    Par seb.49 dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 02/05/2003, 14h52
  5. [langage] Commande DOS dans un programme
    Par Jibees dans le forum Langage
    Réponses: 15
    Dernier message: 23/04/2003, 12h08

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