2016-07-01 4 views
1

Рассмотрим следующий битовое, который я реализовал с союзомВопросы о bitfield?

union 
{ 
    char fullByte; 
    struct 
    { 
     unsigned int bit0: 1; 
     unsigned int bit1: 1; 
     unsigned int bit2: 1; 
     unsigned int bit3: 1; 
     unsigned int bit4: 1; 
     unsigned int bit5: 1; 
     unsigned int bit6: 1; 
     unsigned int bit7: 1; 
    } bitField; 
    struct 
    { 
     unsigned int : 1; 
     unsigned int bit1to6 : 6; 
     unsigned int : 1; 
    } bitField2; 
} bitByte; 

cout << sizeof(bitByte) << endl; //prints 4 
cout << sizeof(bitByte.fullByte) << endl; //prints 1 
cout << sizeof(bitByte.bitField) << endl; //prints 4 
cout << sizeof(bitByte.bitField2) << endl; //prints 4 

Почему объединение и оба Структуры 4 байта? Я определил только 8 бит, не должен ли он быть одним байтом? Если бит равен 2 байтам по определению «unsigned int», не должно ли оно быть 16 байтов? Кажется, что любой способ мышления не работает. Почему это 4 байта?

Кроме того, я замечаю, что я не могу сделать «sizeof (bitByte.bitField.bit0)», каков был бы размер этого? Я определил его как один бит, но без знака int по 2 байта по определению. Сколько байтов будет бит0, бит1 и т. Д.?

+2

"но без знака int по 2 байта по определению." Кто так говорит? – tkausl

+0

@tkausl Хорошо, извините, я думаю, что допустил ошибку. unsigned int - 2 байта или 4 байта. – Thenewstockton

+1

@Thenewstockton no, 'int' может быть 1 байт или 3, 6, 8 байт ... любые значения, если он имеет не менее 16 бит точности. [Что означает стандарт C++ для размера int, длинный тип?] (Http://stackoverflow.com/q/589575/995714). В C –

ответ

0

Почему объединение и структуры как 4 байта?

Размер Союза = наибольший член.

Размер Struct = сумма размеров всех членов (с заполнением).

Итак, в вашем коде SizeOf (bitByte) = SizeOf (bitByte.bitField) ИЛИ SizeOf (bitByte.bitField2)

Я определена только 8 бит, не должна быть один байт?

Заполнение выполняется по той причине, что процессоры требуют, чтобы определенные типы данных имели определенные выравнивания.

+0

нет фиксированного размера. Большое вам спасибо. Я не понимаю, что вы подразумеваете под всеми членами PADDED. Не могли бы вы привести пример? – Thenewstockton

+0

Узнайте об этом http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/. Это очень интересно и информативно. –

+0

Еще раз спасибо. Итак, каков размер каждого бита в структуре? Поскольку unsigned int - это 2 или 4 байта, бит немного? или это что-то вроде 0x0001? – Thenewstockton

0

В союз, выделенное пространство памяти равно члену с наибольшим размером. Все остальные члены имеют одинаковое пространство памяти.

Размер structure будет зависеть от количества bits, который используется для хранения его переменных.

Если требуется 1 to 32 bits для хранения переменных в структуре, то размер структуры будет 4 bytes во всех cases.But как будет требование более 32 bits (скажем 33 бит), то размер структуры будет 8 byte , Это происходит из-за того, что естественное выравнивание на 32-bit machine is 4 bytes. Когда тип данных естественно выровнен, процессор извлекает его в минимальные циклы считывания. Таким образом, размер структуры будет составлять 4 байта до 32 бит. Но если мы хотим хранить 33 переменных, для них потребуется 33 бита, тогда потребуется два цикла считывания памяти ... т.е. 8 байтов

-1

для Int это четыре байта, что является причиной структура также дает 4 байта

, например

struct 
{ 
    unsigned int bit0: 1; 
    unsigned int bit1: 1; 
    unsigned int bit2: 1; 
    unsigned int bit3: 1; 

} bitField; 

в этом случае также вы затворе байт для struct.

0

Вы сказали ему выделить биты из базового unsigned int, который на вашей платформе, по-видимому, составляет 4 байта.

Редактировать: As Chris Dodd points out, компилятор на самом деле не требуется для этого, но я думаю, вам будет трудно найти тот, который этого не делает. Раскладка сетевого пакета важна для большинства систем, поэтому все компиляторы для конкретной архитектуры, как правило, довольно быстро соглашаются на соглашение.

1

Стандарт С указывает на 6.7.2.1:

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

стандарт C++ гораздо более лаконична в 9,6:

Распределение битовых полей в пределах класса объекта определяется реализацией. Выравнивание битовых полей определяется реализацией. Бит-поля упаковываются в некоторые адресные единицы распределения.

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

Нет стандартного определенного постоянного или определенного способа запроса того, что такое размер единицы размещения, хотя термин «определенная реализация» означает, что реализация ДОЛЖНА документировать этот размер где-то.

В вашем конкретном случае кажется, что компилятор выбирает блок распределения 4 байта, так что это то, чем заканчивается размер. Возможно, что другой компилятор может выбрать блок распределения разного размера или даже для одного компилятора для выбора блоков распределения разного размера для разных структур в одной и той же программе. Спецификация особенно не ограничивает.

+0

Стандарт не требует, чтобы компилятор выбирал какой-либо конкретный размер, но обычно принято выбирать размер объявленного базового типа. – jthill