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
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
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...
Normalement je pense que ça marche
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);
Pensez aux tutoriels programmation : http://programmation.developpez.com/cours-tutoriels/
matazz a écrit :Ne s'agit-il pas plutôt de :
Code : Sélectionner tout - Visualiser dans une fenêtre à part UINT16 Result= (UINT16)(temp<<8 & LowByte);OR et non AND
Code : Sélectionner tout - Visualiser dans une fenêtre à part UINT16 Result= (UINT16)HighByte <<8 | (UINT16) LowByte;
Publication : Concepts en C
Mon avatar : Glenn Gould
--------------------------------------------------------------------------
Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
Euh effectivement !!!Envoyé par diogene
Qui va piano va sano...
tu peux essauer de déclarer tes variables autrement :
puis tu mets les octets en place:
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;
et tu récumère le résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 essai.octets[0]=... essai.octets[1]=...
a++
Code : Sélectionner tout - Visualiser dans une fenêtre à part ...=essai.mots;
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.
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;
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...Envoyé par cistamm
alors je vais utiliser les operateur << et |
merci a tous
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.Envoyé par cistamm
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.
l'aide de C++ Builder 4 (c'est le compilateur que j'utilise)
la fin de la descrition corerspond a un exemple.
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.
lorsque l'on écrit une variable on écrase les autres variables de l'union avec sa valeur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 union int_or_long [ int i; long l; } a_number;
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
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.Envoyé par cistamm
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.Envoyé par cistamm
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.
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 ...
Tant que c'est deux machines avec le même nombre de bits, pas de problèmes :
Sur l'un :
Sur l'autre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3int number; file << number;
Par ce problèmes d'inversions.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3int number; file >> number;
Si on veut un fichier en binaire :
Pour lire :
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);
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.
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];
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.
je pensait plutot a quelque chose comme
sur une machine
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 l'autre
Code : Sélectionner tout - Visualiser dans une fenêtre à part write(HandleProduits,&enregistrement,sizeof(Tengistrement));
comment seront lus les stoc ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part read(HandleProduits,&enregistrement,sizeof(Tengistrement));
(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 ... )
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
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 union pointeur { unsigned __int8 *bit8; unsigned __int16 *bit16; unsigned __int32 *bit32; unsigned __int64 *bit64; }
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;\ ... }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 void lit_asm(void) { unsigned __int8 codeop; String resultat; ...
un octet est lu, le pointeur est incrementé en conséquence
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 ... codeop = *(pointeur.bit8++); ...
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
4 octets sont lus le pointeur est incrémenté en consequence
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);
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
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.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager