как разбить 16-значное на два 8-битных значения в C - PullRequest
0 голосов
/ 19 ноября 2018

Я не знаю, если вопрос правильный, но.

Например, десятичное число 25441, двоичный файл - 110001101100001. Как я могу разделить его на два 8-битных "1100011" и "01100001" (что является "99" и "97").Тем не менее, я мог думать только об использовании битовой манипуляции, чтобы сдвинуть его на >> 8, и я не мог сделать остальное для «97».Вот моя функция, она не очень хорошая, но я надеюсь, что она поможет:

void reversecode(int input[], char result[]) {  //input is 25441
int i;
for (i = 0; i < 1; i++) {  
    result[i] = input[i] >> 8;                  // shift by 8 bit
    printf("%i", result[i]);                    //to print result
}
}

Я думал об использовании struct, но у меня нет подсказки для ее запуска.Я начинающий в C, и извините за мой плохой стиль.Спасибо в предварительном.

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Младший младший бит дается простым маскированием с битовой маской: input[i] & 0xFF.

Код, который вы отправили input[i] >> 8, дает следующий байт перед этим.Тем не менее, он также дает все, что было сохранено в старших байтах, в случае, если int равен 32 битам.Итак, снова вам нужно замаскировать, (input[i] >> 8) & 0xFF.

Также избегайте сдвига битов на типах со знаком, таких как int, потому что, если они имеют отрицательные значения, вы вызываете плохо определенное поведение, которое приводит к ошибкам.

Правильный способ маскировать отдельные байты int заключается в следующем:

// 16 bit system  
uint8_t bytes [sizeof(int)] = 
{
  ((uint16_t)i >> 0) & 0xFF,  // shift by 0 not needed, of course, just stylistic
  ((uint16_t)i >> 8) & 0xFF,
};

// 32 bit system  
uint8_t bytes [sizeof(int)] = 
{
  ((uint32_t)i >>  0) & 0xFF,
  ((uint32_t)i >>  8) & 0xFF,
  ((uint32_t)i >> 16) & 0xFF,
  ((uint32_t)i >> 24) & 0xFF,
};

Это помещает младший бит в индекс 0 в этом массиве, аналогично представлению Little Endian в памяти.Тем не менее, обратите внимание, что фактический битовый сдвиг не зависит от порядка байтов и также является быстрым, поэтому это превосходный метод.

Решения, основанные на объединениях или арифметике указателей, зависят от порядка байтов и часто содержат ошибки (нарушения псевдонимов указателей)поэтому их следует избегать, поскольку их использование бесполезно.

0 голосов
/ 19 ноября 2018

Вы можете использовать концепцию битовой маскировки.
Таким образом,

uint16_t val = 0xABCD;
uint8_t vr  = (uint8_t) (val & 0x00FF);

Или это также можно сделать просто явным приведением типа, поскольку 8-разрядное целое число переносит только 8-разрядные биты LBS из 16-разрядного значения и отбрасываетостальные 8-разрядные MSB (по умолчанию, когда назначается большее значение).Это все сделано после сдвига битов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...