J'ai défini deux variables:
uint8_t a[2];
uint16_t b;
Ensuite, je veux utiliser a
comme variable de type uint16_t
, par exemple
b = (uint16_t)a;
Mais c'est faux! Mes programmes ne fonctionnent pas correctement avec un tel code. Tout est OK lorsque je remplace b
à uint8_t b[2]
et de l' exploitation de l' utilisation par éléments.
Pourquoi?
Réponses:
a
est un pointeur vers un tableau d'octets. Si vous le transformez en uint16_t et l'affectez àb
, alorsb
contiendra l'adresse de la base du tableau (où il est stocké) dans SRAM. Si vous souhaitez traiter les deux octets du tableaua
comme un entier, utilisez une union comme suggéré par user14284, mais sachez que l'union représentera le tableau d'octets dans l'ordre des octets de la mémoire de l'architecture (dans AVR, ce serait peu -endian, ce qui signifie que l'octet 0 est l'octet le moins significatif). La façon d'écrire cela dans le code est:Une autre façon de le faire sans utiliser l'union est de
a
transtyper en un pointeur uint16_t puis de le déréférencer comme ceci:Si vous utilisez le tampon pour stocker de grandes données endiennes (par exemple, l'ordre des octets du réseau), vous devrez alors permuter les octets pour utiliser l'une de ces techniques. Un moyen de le faire sans aucune branche ni variable temporaire est:
Soit dit en passant, ce n'est pas un AVR ou même un problème intégré uniquement. Niveau d'application code réseau sur des PC appels généralement appelés fonctions
htonl
,htons
(hôte réseau, et 16 32- bits variantes) etntohl
,ntohs
(réseau hôte, et les variantes 32- 16 bits) dont la mise en oeuvre sont l' architecture cible dépend de savoir si elles permutez ou non les octets (en supposant que les octets tels qu'ils sont transmis «sur le câble» sont toujours en gros bout quand ils font partie de mots à plusieurs octets).la source
a
' seule est un pointeur.-fno-strict-aliasing
.Si votre intention est de concaténer les deux variables 8 bits en une variable 16 bits, utilisez a
union
. Si vous souhaiteza
convertir un seul membre de enb
, spécifiez l'élément du tableau que vous souhaitez utiliser.la source
Sur votre code, vous ne transformez que le pointeur sur le tableau.
Vous devez convertir la valeur indiquée par
a
.Je n'ai jamais utilisé AVR mais si vous travaillez avec une architecture 16 bits, vous devez vous assurer qu'un mot est aligné. Ne pas le faire peut entraîner une exception.
la source
Chaque membre d' un est un nombre de 8 bits. Il ne peut rien contenir de plus gros. Le convertir en 16 bits ne fait rien pour a . Il extrait simplement la valeur que pourrait contenir a et la convertit en 16 bits afin qu'elle corresponde au format de b lorsque la valeur y est stockée.
Vous n'avez même pas fait référence à un membre d' un . Vous devez utiliser un [0] ou un [1] (et non un [2]!). Si vous utilisez un seul, vous obtenez simplement l'adresse de celui-ci. (Bonne prise, Bruno).
Déclarer un comme un tableau de deux nombres à 8 bits n'en fait pas non plus un nombre à 16 bits. Vous pouvez faire certaines choses par programmation pour stocker et récupérer des valeurs 16 bits en utilisant des séquences de 8 bits, mais pas comme vous le pensiez.
la source
Si vous souhaitez convertir les octets
a
en une valeur de 16 bits et que la représentation est en petit-boutien (les 8 bits inférieurs de la valeur viennent dans le premier octet), faitesPour une représentation big-endienne,
Évitez d'utiliser des pointeurs ou des unions pour ce faire, car cela entraîne des problèmes de portabilité.
la source