2012-06-05 4 views
1

Если у меня есть 16 бит, которые представляют 3 пары значений, каждый из 5 бит и еще одно 1-битное значение в точно таком порядке, можно ли использовать бит-поле для описания этого? Означает ли ANSI C, что бит будет точно в том порядке, который я укажу?Представление отдельных битов в C

struct { 
    unsigned v1 : 5; 
    unsigned v2 : 5; 
    unsigned v3 : 5; 
    unsigned v4 : 1; 
} test; 

Если нет, есть ли какая-либо другая структура данных, которую я могу использовать для представления этого? Или я должен просто хранить два 8 бит char и управлять ими программно, чтобы быть уверенным в переносимости?

ответ

4

Соответствующие цитат я смог найти 6.7.2.1 (1), от C99:

Реализация может выделить любой адресуемый блок хранения достаточно большой, чтобы провести битовый поля. Если остается достаточно места, бит-поле, которое сразу следует за другим битовым полем в структуре , должно быть упаковано в соседние биты того же блока. Если недостаточно места, то будет ли бит-поле, которое не подходит, помещается в следующий блок или перекрывает смежные единицы, определяется реализацией. Порядок распределения бит-полей внутри единицы (от высокого порядка до младшего или низкого порядка) определяется реализацией. Выравнивание адресного блока хранения не указывается.

Я думаю, что unsigned не на самом деле типа «основной блок», но, скорее, это лишь часть самого битовой декларации: T : n означает «взять п бит типа T». Реальный вопрос заключается в том, требуется ли , чтобы выбрать «большую» единицу. Например, он может использовать три байта, сделав блок char; один для v1, один для v2, а последний для v3, v4. Или это может сделать блок 16-битным целым числом, и в этом случае потребуется использовать только одну единицу.

Однако, как вы отметили, заказ заказанных полей не содержит никаких полей. Атомная единица данных в C является адресом , а битовые поля не имеют адресов. Гарантируется, что адрес членов структуры увеличивается в порядке их объявления, но вы не можете сделать такой вывод о битовых полях (только об их базовых единицах).

+0

Hrm, который не указывает точно, как биты должны быть заказаны. – rid

+0

@Radu: Вы правы. Я расширил цитату, и я думаю, что ответ «определяется реализацией». –

+0

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

1

Вы можете использовать тип uint16_t от stdint.h, который гарантированно будет синонимом типа для 16-битного количества без знака. Если вас беспокоит сущность, это становится более сложным.

+0

Значит, бит не может быть указан в указанном вами порядке, поэтому я должен вручную манипулировать данными? – rid

+0

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

0

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

Вот ответ, который я только что написал о том, как использовать битовые поля для извлечения некоторых битов из байтового значения. Когда я написал это, я обнаружил, что мне нужно добавить #pragma pack(1), иначе мои битовые поля не поместились в один байт.

Access bits in a char in C

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

Смежные вопросы