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 :

concatener des bits


Sujet :

C++

  1. #1
    Membre habitué
    Inscrit en
    Avril 2002
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 180
    Points : 157
    Points
    157
    Par défaut concatener des bits
    salut
    mes variable sont defini ainsi

    typefef unsigned char BYTE /*8 bits*/
    typedef unsigned short UINT16 /*16 bits*/

    je veut metre 2 BYTE une a la suite de l'autre dans un UINT16;

    et j'ai aucunne idee comment

    merci

  2. #2
    Membre éclairé
    Avatar de matazz
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    471
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 471
    Points : 668
    Points
    668
    Par défaut
    tu veut veut transformer 0x21 et 0xEF en 0x21EF ?
    Si oui ça devrait marcher (Il doit y avoir un moyen plus simple si tes 2 variables sont contigues en mémoire, mais bon):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    BYTE HighByte = 0x21;
    BYTE LowByte = 0xEF;
     
    UINT16 temp = (UINT16)HighByte ;
     
    UINT16 Result= (UINT16)(temp<<8 & LowByte);
    Qui va piano va sano...

  3. #3
    Membre averti Avatar de Bob.Killer
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    336
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 336
    Points : 332
    Points
    332
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UINT16 _uint16=0;
    BYTE b1 = 10, b2 = 3;
    printf("%d\n",_uint16);
    _uint16 = b1;
    printf("%d\n",_uint16);
    _uint16 <<= 8;
    printf("%d\n",_uint16);
    _uint16 += b2;
    printf("%d\n",_uint16);
    Normalement je pense que ça marche
    Pensez aux tutoriels programmation : http://programmation.developpez.com/cours-tutoriels/

  4. #4
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    matazz a écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UINT16 Result= (UINT16)(temp<<8 & LowByte);
    Ne s'agit-il pas plutôt de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UINT16 Result= (UINT16)HighByte <<8 | (UINT16) LowByte;
    OR et non AND
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Membre éclairé
    Avatar de matazz
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    471
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 471
    Points : 668
    Points
    668
    Par défaut
    Citation Envoyé par diogene
    matazz a écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UINT16 Result= (UINT16)(temp<<8 & LowByte);
    Ne s'agit-il pas plutôt de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UINT16 Result= (UINT16)HighByte <<8 | (UINT16) LowByte;
    OR et non AND
    Euh effectivement !!!
    Qui va piano va sano...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Points : 17
    Points
    17
    Par défaut
    tu peux essauer de déclarer tes variables autrement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    union union_octets_mots
    {   octets unsigned __int8[2];
         mots unsigned __int16;
    }essai;
    puis tu mets les octets en place:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    essai.octets[0]=...
    essai.octets[1]=...
    et tu récumère le résultat :
    a++

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Utiliser une union ainsi déclanche un comportement indéfini du C++. Tout peut arriver.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Points : 17
    Points
    17
    Par défaut
    le comprtement de C++ dans ce cas est tres clair :
    les union_octets_mots auront une taille de 2 octets et suivant la façon dont on y accède ils seront considérés comme un tableau de 2 __int8 ou 1 __int16;

  9. #9
    Membre habitué
    Inscrit en
    Avril 2002
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 180
    Points : 157
    Points
    157
    Par défaut
    Citation Envoyé par cistamm
    tu peux essauer de déclarer tes variables autrement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    union union_octets_mots
    {   octets unsigned __int8[2];
         mots unsigned __int16;
    }essai;
    puis tu mets les octets en place:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    essai.octets[0]=...
    essai.octets[1]=...
    et tu récumère le résultat :
    a++
    en effait ca fonctionne et j'aime bien le look. Mais j'ai pas le droit de changer la declaration des variable qestion de compatibiliter avec les ancienne version et blablabla...
    alors je vais utiliser les operateur << et |

    merci a tous

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par cistamm
    le comprtement de C++ dans ce cas est tres clair :
    les union_octets_mots auront une taille de 2 octets et suivant la façon dont on y accède ils seront considérés comme un tableau de 2 __int8 ou 1 __int16;
    Désolé de te contredire, mais je suis sur de mon coup. Note qu'un comportement indéfini peut très bien avoir été défini par un compilateur particulier pour faire ce que tu veux, mais rien n'est garanti que ça continue de marcher avec un autre compilateur.

    Un petit extrait de la norme pour appuyer mes dires (la première phrase est la plus importante) :
    9.5 Unions
    In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time. [Note: one special guarantee is made in order to
    simplify the use of unions: If a PODunion contains several PODstructs
    that share a common initial sequence (9.2), and if an object of this PODunion type contains one of the PODstructs, it is permitted to
    inspect the common initial sequence of any of PODstruct members; see 9.2. ]
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Points : 17
    Points
    17
    Par défaut
    l'aide de C++ Builder 4 (c'est le compilateur que j'utilise)
    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
    Categorie
     
    Spécificateurs de type
     
    Syntaxe
     
    union [<nom type union>] {
     
      <type> <noms variable> ;
      ...
     
    } [<variables union>] ;
     
    Description
     
    union permet de définir des variables qui partagent l'espace de stockage.
     
    Le compilateur alloue suffisamment de stockage dans a_number pour pouvoir s'adapter à l'élément le plus grand de l'union.
     
    A l'inverse d'une struct, les variables a_number.i et a_number.l occupent le même emplacement en mémoire. Ainsi, l'écriture dans une variable écrase l'autre.
     
    Utilisez le sélecteur d'enregistrement (.) pour accéder aux éléments d'une union.
    la fin de la descrition corerspond a un exemple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    union int_or_long [
      int     i;
      long   l;
    } a_number;
    lorsque l'on écrit une variable on écrase les autres variables de l'union avec sa valeur.
    A ce momont 2 cas différents sont à distinguer
    ou bien les types sont incompatibles les variables autres que la derniere affectée seront incohéerntes.
    ou bien (comme comme dans l'exemple de 2 octets ou un mot , il est clair que si l'on écrase les 2 octets d'un mot l'un après l'autre, on conserve un mot tout a fait cohérent) le fait d'écraser une variable avec une autre consiste a lui attribuer une nouvelle valeur.
    Si l'on a besoin d'une pensée unique qui fonctionne dans tous les cas on est obigé de tenir compte du premier cas et effectivement on constate que en affectant une valeur a une variable d(une union, il est possible que cela rende iillisible une ou plusieurs des autres.
    Je ne connais pas la norme dont tu marle mais visiblement personne n'a pris la peine de la traduire en français , donc elle n'est surement pas destinée à être utilisée par tout le monde...
    Cistamm

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par cistamm
    lorsque l'on écrit une variable on écrase les autres variables de l'union avec sa valeur.
    A ce momont 2 cas différents sont à distinguer
    ou bien les types sont incompatibles les variables autres que la derniere affectée seront incohéerntes.

    ou bien (comme comme dans l'exemple de 2 octets ou un mot , il est clair que si l'on écrase les 2 octets d'un mot l'un après l'autre, on conserve un mot tout a fait cohérent) le fait d'écraser une variable avec une autre consiste a lui attribuer une nouvelle valeur.
    En théorie, rien n'est garanti. Dans la pratique, il ce peut que ça marche, j'ai vu des machines où mettre 0x12 dans octets[0] et 0x34 dans octets[1] donnait pour valeur soit mots == 0x1234, soit mots == 0x3412. Et pour ça, pas besoin de chercher des architectures exotiques (je pense qu'il doit y avoir des architectures où il est possible d'avoir des choses encore plus étranges). Donc autant faire du code aussi simple qui marche dans tous les cas que de prendre un risque.

    Citation Envoyé par cistamm
    Je ne connais pas la norme dont tu marle mais visiblement personne n'a pris la peine de la traduire en français , donc elle n'est surement pas destinée à être utilisée par tout le monde...
    Il s'agit du document ISO/IEC 14882. C'est lui qui défini ce qu'est le C++. Il est possible de s'en procurer le pdf pour $18, mais effectivement, il est de lecture un peu ardue.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Points : 17
    Points
    17
    Par défaut
    Il n'y a pas besoin de passer par "union" pour avoir des problèmes de compatibilite entre les ordis qui inverse les octets de poids faible et fort et ceux qui ne les inverse pas.
    Essaie d'écrire un fichier contenant des valeurs numériques sur l'un et de le lire sur l'autre ...

  14. #14
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Tant que c'est deux machines avec le même nombre de bits, pas de problèmes :

    Sur l'un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int number;
    file << number;
    Sur l'autre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int number;
    file >> number;
    Par ce problèmes d'inversions.

    Si on veut un fichier en binaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int number;
    unsigned char encode[2];
    encode[0] = number & 0xFF;
    encode[1] = (number >> 8) & 0xFF;
    file.write(encode, 2);
    Pour lire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int number;
    unsigned char decode[2];
    file.read(decode, 2);
    number = decode [1];
    number = (number << 8) & decode[0];
    Toujours pas de problèmes d'inversion. Tant qu'on ne fait pas d'opérations non définies, il n'y a pas de problèmes de ce genre. Et dans ce cas, le problème est plus gênant, puisqu'il suffit avec la mauvaise union d'une seule machine pour avoir un comportement gênant.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Points : 17
    Points
    17
    Par défaut
    je pensait plutot a quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Tenregistrement struct
    {    char designation [25];
         char reference[10];
         int stoc;
    ...
    } enregistement;
    sur une machine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    write(HandleProduits,&enregistrement,sizeof(Tengistrement));
    sur l'autre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(HandleProduits,&enregistrement,sizeof(Tengistrement));
    comment seront lus les stoc ?
    (si l'on veux etre sur que les 2 machines travailles sur le meme nombre de bit on peut remplacer int par __int16 ou __int32 ... )

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 14
    Points : 17
    Points
    17
    Par défaut
    un autre exemple ou j'au déjà utilisé union pour faire du tyranstypage :
    je ne donne pas vraiment le code mais j'en extrait ce qui concerne l'utilisation de union en ayant au même moment plusieur de ces variables accessibles
    dans une routine de désasemblage de code binaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    union pointeur
    {   unsigned __int8 *bit8;
       unsigned __int16 *bit16;
       unsigned __int32 *bit32;
       unsigned __int64 *bit64;
    }
    le pointeur parcoure toute la zone mémoire a étudier en se comprotant différemment:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #define macro_reg1(numeroRegistre)\
    swith(numeroRegistre)\
    {   case 0:\
         resultat+="eax";\
         break;\
        case 1:\
         resultat+="ecx";\
         break;\
        case 2:\
         resultat+="edx";\
         break;\
    ...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void lit_asm(void)
    {  unsigned __int8 codeop;
        String resultat;
    ...
    au début de la boucle principale il est utilisé comme pointeur sur octet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ...
    codeop = *(pointeur.bit8++);
    ...
    un octet est lu, le pointeur est incrementé en conséquence

    une série de tests sur codeop permettent de déterminer la suite
    ...
    on ss lpace maintenant dans le cas ou la valeur de codeop en binaire est 1011 1???
    qui correspont a l'instruction MOV reg32,imm32
    les 3 derniers bits de codeop donnent le registre que l'on récupere avec macro_reg1
    la valeur immédiate est stockée dans les 4 octéts suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       resultat="MOV ";
       macro_reg1(codeop&7)
       resultat+=" , ";
       resultat+=IntToHex(*(pointeur.bit32++) , 8);
    4 octets sont lus le pointeur est incrémenté en consequence
    en permanance pointeur est dirigé vers le prochain octet à lire
    lorsue l'on les une valeur
    *(pointeur.bit8++)
    *(pointeur.bit16++)
    *(pointeur.bit32++)
    *(pointeur.bit64++) permettent de récupérer 1, 2, 4 ou 8 octets en redirigeant pointeur vers le nouvel octet a lire

    toi , si tu choisi d'appliquer les règles de la Norme tu en a parfaitement le droit
    mais moi , je trouve très pratique d'utiliser "union" pour faire du transtypage

  17. #17
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Rien n'est garanti. En plus de problème d'ordre de bits, tu pourrais aussi avoir des problèmes de padding. Mais tout ça viens du fait qu'à un moment, tu cast depuis char* vers TEnregistrement * (par un cast qui est moralement équivalent à du reinterpret_cast).

    Ceci n'est autorisé que si ce qui est pointé par le void * est déjà un TEnregistrement, ce qui n'est pas le cas ici.

    Moralité : On ne sauve jamais des données binaires ainsi quand on prétend à la moindre compatibilité. On le fait champ à champ et char par char.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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

Discussions similaires

  1. [VB.NET] Concaténer des images
    Par franculo_caoulene dans le forum ASP.NET
    Réponses: 5
    Dernier message: 26/11/2004, 16h57
  2. concatenation des données d'une table dans une autre
    Par Fabby69 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 04/10/2004, 11h38
  3. Grouper et concatener des résultats
    Par Koo dans le forum Langage SQL
    Réponses: 3
    Dernier message: 07/07/2004, 10h09
  4. Travailler avec des bits
    Par Vulvulune dans le forum Langage
    Réponses: 5
    Dernier message: 02/03/2003, 19h09
  5. Question : ordre des bits ?
    Par Choupi dans le forum C
    Réponses: 3
    Dernier message: 11/02/2003, 06h22

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