Как разбить длинное значение (32 бита) на четыре переменные char (8 бит) с помощью C?

У меня есть 32-битная переменная, CurrentPosition, которую я хочу разделить на 4, 8-битные символы. Как бы я сделал это наиболее эффективно в C? Я работаю с 8 бит микроконтроллер, architectecture 8051.

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? 

должен ли я просто ссылаться на начальный адрес CurrentPosition с указателем, а затем добавить 8 два адреса четыре раза?

Это маленький Эндиан.

также Я хочу, чтобы CurrentPosition оставался неизменным.

6 ответов


    CP1 = (CurrentPosition & 0xff000000UL) >> 24;
    CP2 = (CurrentPosition & 0x00ff0000UL) >> 16;
    CP3 = (CurrentPosition & 0x0000ff00UL) >>  8;
    CP4 = (CurrentPosition & 0x000000ffUL)      ;

вы также можете получить доступ к байтам через указатель,

unsigned char *p = (unsigned char*)&CurrentPosition;
//use p[0],p[1],p[2],p[3] to access the bytes.

Я думаю, вы должны рассмотреть возможность использования Союза:

union {
   unsigned long position;
   unsigned char bytes[4];
} CurrentPosition;

CurrentPosition.position = 7654321;

байты теперь могут быть доступны как: CurrentPosition.байт[0], ..., Текущий положение знака.байт[3]


Если вы используете 8-битный MCU, смещающий всю 32-битную переменную, это немного работы. В этом случае лучше прочитать 4 байта CurrentPosition, используя арифметику указателя. Актеры:

unsigned char *p = (unsigned char*)&CurrentPosition;

не изменяет CurrentPosition, но если вы попытаетесь записать в p[0], вы измените наименее значимый байт CurrentPosition. Если вам нужна копия, сделайте следующее:

unsigned char *p = (unsigned char*)&CurrentPosition;
unsigned char arr[4];
arr[0] = p[0];
arr[1] = p[1];
arr[2] = p[2];
arr[3] = p[3];

и работать с arr. (Если вы хотите, чтобы самый значительный байт сначала изменил порядок в них назначения.)

Если вы предпочитаете 4 переменные, вы, очевидно, можете сделать:

unsigned char CP1 = p[0];
unsigned char CP2 = p[1];
unsigned char CP3 = p[2];
unsigned char CP4 = p[3];

CP1 = (unsigned char)(CurrentPosition & 0xFF);
CurrentPosition >>= 8;
CP2 = (unsigned char)(CurrentPosition & 0xFF);
...

unsigned char *CP = &CurrentPosition;

теперь CPn на ваш исходный код доступен через CP[n].


Я знаю, что это было опубликовано некоторое время назад. Но для тех, кто все еще читает нить: Многие люди используют метод последовательного смещения первоначальной стоимости. Почему бы не позволить компилятору сделать работу за вас. Используйте union &, чтобы сохранить значения в одном месте. Определите объединение, состоящее как из 32-битной переменной (здесь вы сохраните свою текущую позицию), так и из структуры, состоящей из 4 переменных char. Или просто 8-битный целочисленный массив. Когда ты пишешь CurrentPosition к длинной переменной, он будет храниться в том же месте, доступном при чтении 4 переменных char. Этот метод намного менее трудоемкий и не позволяет компилятору выполнять работу вместо того, чтобы тратить время и ресурсы.