Как разделить длинное значение (32 бита) на четыре переменные типа char (8 бит), используя C? - PullRequest
10 голосов
/ 30 апреля 2010

У меня есть 32-битная переменная CurrentPosition, которую я хочу разделить на 4, 8-битные символы. Как бы я сделал это наиболее эффективно в C? Я работаю с 8-битной микроконтроллером, 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 два по этому адресу четыре раза?

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

ТАКЖЕ я хочу, чтобы CurrentPosition оставалось неизменным.

Ответы [ 6 ]

17 голосов
/ 30 апреля 2010
    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.
7 голосов
/ 01 мая 2010

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

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

CurrentPosition.position = 7654321;

Байты теперь доступны как: CurrentPosition.bytes [0], ..., CurrentPosition.bytes [3]

2 голосов
/ 01 мая 2010

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

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

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

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];

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

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

unsigned char CP1 = p[0];
unsigned char CP2 = p[1];
unsigned char CP3 = p[2];
unsigned char CP4 = p[3];
0 голосов
/ 05 января 2018

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

0 голосов
/ 01 мая 2010
unsigned char *CP = &CurrentPosition;

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

0 голосов
/ 30 апреля 2010
CP1 = (unsigned char)(CurrentPosition & 0xFF);
CurrentPosition >>= 8;
CP2 = (unsigned char)(CurrentPosition & 0xFF);
...
...