2015-12-05 2 views
2

Скажите, что у вас есть целое число, и вы хотите преобразовать его в массив байтов. После поиска в разных местах я видел два способа сделать это: один с сдвигом, а один - сдвигом, затем маской. Я понимаю смещающуюся часть, но зачем маскировать?Маска или нет маски при преобразовании int в байтовый массив?

Например, сценарий 1:

uint8 someByteArray[4]; 
uint32 someInt; 

someByteArray[0] = someInt >> 24; 
someByteArray[1] = someInt >> 16; 
someByteArray[2] = someInt >> 8; 
someByteArray[3] = someInt; 

Сценарий 2:

uint8 someByteArray[4]; 
uint32 someInt; 

someByteArray[0] = (someInt >> 24) & 0xFF; 
someByteArray[1] = (someInt >> 16) & 0xFF; 
someByteArray[2] = (someInt >> 8) & 0xFF; 
someByteArray[3] = someInt & 0xFF; 

Есть ли причина выбрать один над другим?

+1

В этом конкретном коде маска является избыточной. Другие варианты кода могут понадобиться. Кроме того, некоторые компиляторы дают ложные предупреждения, если вы не маскируете. –

+0

@YuHao Исправлено, спасибо! –

+0

Если вам не нужна маска, ее устранение может сэкономить четыре инструкции «и». – Davislor

ответ

1

uint8 и uint32 не являются стандартными типами C. Я предполагаю, что они представляют собой 8-битные и 32-разрядные беззнаковые интегральные типы, соответственно (например, поддерживаемые компиляторами Microsoft в качестве расширения для конкретного поставщика).

В любом случае ....

Маскирующий является более общим - это гарантирует результат между 0 и 0xFF независимо от фактического типа элементов someByteArray или someInt.

В данном конкретном случае, это не имеет никакого значения, так как преобразование uint32 в uint8 гарантировано использовать арифметические операции по модулю (по модулю 0xFF + 0x01 которая равна 0x100 или 256 в десятичной системе). Однако, если ваш код изменен для использования переменных или массивов разных типов, маскирование необходимо для обеспечения того, чтобы результат находился между 0 и 255 (включительно).

С некоторыми составителями маскирующий останавливает предупреждения компилятора (он эффективно указывает компилятору, что выражение производит значение между 0 и 0xFF, которые могут быть сохранены в 8 бит unsigned). Однако некоторые другие компиляторы жалуются на акт преобразования большего типа в 8-битный тип. Из-за этого вы иногда видите третий вариант, который на самом деле демонстрирует мышление «ремни и подтяжки».

uint8 someByteArray[4]; 
uint32 someInt; 

someByteArray[0] = (uint8)((someInt >> 24) & 0xFF); 
someByteArray[1] = (uint8)(someInt >> 16) & 0xFF); 
someByteArray[2] = (uint8)((someInt >> 8) & 0xFF); 
someByteArray[3] = (uint8)(someInt & 0xFF); 
Смежные вопросы