J'ai une variable de 32 bits de longue durée de 32 bits, une exposition de courant, que je veux diviser en 4 plats 8 bits. Comment ferais-je le plus efficacement en C? Je travaille avec un MCU 8 bits, 8051 architececture.
unsigned long CurrentPosition = 7654321; unsigned char CP1 = 0; unsigned char CP2 = 0; unsigned char CP3 = 0; unsigned char CP4 = 0; // What do I do next?
6 Réponses :
CP1 = (unsigned char)(CurrentPosition & 0xFF); CurrentPosition >>= 8; CP2 = (unsigned char)(CurrentPosition & 0xFF); ...
Cela modifierait la valeur dans la prochaine position? Je veux laisser la présente exposition inchangée.
Oui, une option est de faire une copie de l'exposition de courant et de la copie. Ou la réponse de nos NOS est une autre option. Votre idée d'utiliser un pointeur est également possible. Il y a beaucoup de façons de faire cela.
unsigned char *p = (unsigned char*)&CurrentPosition; //use p[0],p[1],p[2],p[3] to access the bytes.
1) Dois-je les jeter avec (sans signification)? 2) Est-ce que cela laissait la présente exposition non affectée?
1. Le premier aura besoin de casting 2. Les deux méthodes laissent la présente exposition non affectée
Le premier n'est pas besoin de casting i>, mais certains compilateurs donneront un avertissement de fouilles sur une éventuelle perte de précision si vous ne le faites pas.
Notez que la version bit-shift est neutre de l'Endian, le rend plus portable.
Si vous utilisez un MCU à 8 bits, une variable de 32 bits est un peu de travail. Dans ce cas, il vaut mieux lire 4 octets de la présente exposition à l'aide de l'arithmétique du pointeur. Le casting:
unsigned char CP1 = p[0]; unsigned char CP2 = p[1]; unsigned char CP3 = p[2]; unsigned char CP4 = p[3];
Ce Soln est préférable que vous ne puissiez pas changer de 32 bits directement directement.
Je pense que vous devriez envisager d'utiliser un syndicat:
union { unsigned long position; unsigned char bytes[4]; } CurrentPosition; CurrentPosition.position = 7654321;
Une bonne idée dans la pratique car le compilateur peut faire la décomposition de l'INT en octets. Une mauvaise idée en théorie parce que cet usage des syndicats est indéfini par la norme C. (La plupart des implémentations non toutes de la mise en œuvre ne fonctionneront que)
@NILS Type Punning avec les syndicats a été bien défini depuis C99. Le code est toujours endian dépendant cependant.
unsigned char *CP = &CurrentPosition; Now CPn per your original code is accessed via CP[n].
Je sais que cela a été posté il y a quelque temps. Mais pour que quiconque lisait toujours le fil: Beaucoup de gens prennent l'approche de transférer séquentiellement la valeur initiale. Pourquoi ne pas laisser le compilateur faire le travail pour vous. Utilisez un syndicat et pour vous permettre de stocker les valeurs au même endroit. Définissez une union composée d'une variable de 32 bits longue (ce sera l'endroit où vous enregistrez votre position) et une structure composée de 4 variables de caractères. Ou juste un simple tableau entier 8 bits. Lorsque vous écrivez votre postition à la variable longue, il sera stocké au même endroit où vous avez lu les 4 variables de caractères. Cette méthode est beaucoup moins intense de travail et ne permet pas au compilateur de faire le travail au lieu de perdre du temps et des ressources. P>
C'est exactement ce que La deuxième réponse la plus avancée suggère.
J'utilise SDCC avec utilise le petit format Endian