Как получить доступ к одному байту целого числа?

Для указанного стандарта связи RTCM SC104 3.1 мне нужно разделить данные между байтами в виде пары 12-битных сегментов данных. Поэтому для данного сообщения мне нужно поместить номер типа сообщения в первый байт и половину второго байта. Затем мне нужно запустить целое число идентификатора в половине второго байта и продолжить до третьего байта. Этот тип шаблона продолжается до конца сообщения, сбивая другие целые числа в 20-битном, 5-битном и других размерах, по существу сокращая 0, которые обычно заполняют конец целых значений MSB.

Я не видел четкого определения, но я предполагаю, что оно должно выходить в сетевом порядке байтов, поэтому, прежде чем копировать биты, я должен был бы обратить свои целые числа в памяти.
Я все еще новичок в cpp и мне интересно, как мне добраться до отдельных байтов, составляющих целое число в памяти? Если бы я мог получить доступ к байтам, то я мог бы использовать побитовое или разделить биты из 2 байтов на один для сообщения.

Вот начало построения сообщения перед добавлением данных:

//build message 1002  gps 00111110 1010
char buf1002[BUFFERSIZE];
buf1002[0] = 0x3E; //00111110
buf1002[1] = 0xA0; //10100000
//ref station id 12 bits of 16
//ex unsigned short m = 1100;
//m would be byte2 00000100 byte1 01001100
//buf1002[1] would be 10100100
//buf1002[2] would be 01001100
//reverse bit order for network after building?

Опорная станция будет с короткого знака без знака, так что это 2-байтовое целое число. Так как же мне прочитать один байт? Должен ли я начать с указателя местоположения памяти? Если так, то что?

Любая помощь будет принята с благодарностью.

6

Решение

Вы можете использовать битовые поля, например, несколько предупреждений в конце:

typedef union packet {
struct {
unsigned int msgno  : 12; // creates a 12 bit wide integral field
unsigned int msgtype  : 12;
unsigned int somefield2  : 3;
unsigned int somefield3  : 5;
} fields;

unsigned char asbytes[4];
} packet;

...

packet p;
// fill it, by using the field side of the union
p.fields.msgno = 16;
p.fields.msgtype = 12;
p.fields.somefield2 = 6;
// and retrieving them as regular bytes
unsigned char abyte = p.asbytes[0];
abyte = p.asbytes[1];
// and so on

Для меня главным преимуществом является удобочитаемость: все операции ведут себя как обычные операции над хотя бы более узкими переменными целочисленного типа. Существуют ограничения (например, переносимость), но если вам не нужно ориентироваться на несколько архитектур, компиляторов или разные порядковые номера, это может сделать вашу программу намного проще для чтения.

4

Другие решения

Если у вас целое число, например, похожее на 00001000 00000000 11000000 00110000 (я делаю пробелы для различия каждого байта), содержащееся в примере в int a:

int     a;
int     single_byte;

a = the_number;

Вы могли бы сделать такую ​​функцию, как

int     get_byte_in_integer(int byte_number, int integer);

Чтобы:

single_byte = get_byte_in_integer(1, a); // That would give you the 11000000 byte

с

int    get_byte_in_integer(int byte_number, int integer)
{
return (integer >> (byte_number << 3)) & 0xff);
}

Надеюсь, это поможет, со стороны байта.

2

Вы можете прибегнуть к наказанию в байтах, например:

const unsigned short s(1);
const char* const bytes(reinterpret_cast<const char*>(&s));

const char NaturalOrder[sizeof(s)] = {bytes[0],bytes[1]};
const char EndianFlipped[sizeof(s)] = {bytes[1],bytes[0]};

(Но также посмотрите комментарий dmckee относительно естественного размера встроенных элементов и рассмотрите возможность использования типов фиксированной ширины).

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector