У мові С ++ є можливість задавати елементам структур певну кількість пам'яті в бітах. Наприклад, якщо необхідно створити структуру даних, що відповідає розміру регістра в будь-якому пристрої. типом елемента (його називають двійкового полем) такої структури може бути целочисленное (найчастіше типу непідписаний) или перелічуваних (enum).
Синтаксично бітове поле в структурі визначається наступним чином:
Наприклад:
1 2 3 4 5 6 | struct fieldbite { unsigned short first : 2; unsigned short second: 2; unsigned short third : 4; } field; |
Ми визначили структуру, в якій змінні будуть займати вказану кількість біт. 2 + 2 + 4 дає 8 біт (ми вирівняли до розміру байта). Якщо в цю структуру дописати ще непідписаний short п'ятий : 5; – вже буде задіяно 2 байта. У другому байті природно буде сміття 8 – 5 = 3 біти, які будуть незатребуваними.
На відміну від об'єднань (union) розмір бітових полів варіюється, в залежності від того, скільки біт програміст замовив. якщо замовлено 7 біт (скажімо дві змінні по 3 біти, і одна – 1 біт), то С ++ відведе один байт (8 біт) під ці три змінні.
Якщо програміст замовить 11 біт, то С ++ відведе два байта (16 біт). Причому в другому байті будуть задіяні тільки 5 біт, а решта швидше за все будуть, як непотрібний хвіст. Тому при описі бітових полів слід враховувати таке “вирівнювання” до байта. Тобто,. розподіляти в ньому змінні так, щоб кожен біт був затребуваний. Для вирівнювання займаної пам'яті можна використовувати неіменовані бітові поля.
Наведемо ще один короткий приклад, в якому бітові поля відводяться під дату і час для демонстрації цієї технології.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <iostream> using namespace std; struct DateTime //Опишем структуру с битовыми полями { unsigned short Day : 5; //5 бит для дня unsigned short Month : 4; //4 для месяца unsigned short Year : 7; //7 для года от 0 до 99 unsigned short Hour : 5; //5 бит для 24-х часов unsigned short Minute : 6;//6 для минут unsigned short Second : 6;//6 для секунд }; int main() { DateTime d; //объявляем переменную этого типа с битовыми полями int i; //И еще одну, в которую будет поступать ввод данных //Введем дату cout << "Input day (1-31):" << '\t'; cin >> i; d.Day = i; cout << "Input month (1-12):" << '\t'; cin >> i; d.Month = i; cout << "Input Year (00-99) :" << '\t'; cin >> i; d.Year = i; //Введем время cout << endl << "Input Hour (0-24):" << '\t'; cin >> i; d.Hour = i; cout << "Input Minute (0-60):" << '\t'; cin >> i; d.Minute = i; cout << "Input Seconds (0-60):" << '\t'; cin >> i; d.Second = i; //И выведем их с показателем размера в памяти cout << endl << "Date is: " << d.Day << "." << d.Month << ".20" << d.Year << " "; cout << d.Hour << ":" << d.Minute << ":" << d.Second << endl; cout << sizeof(d) << endl; } |
Результат:
Як бачите, бітові поля зберігають дату і час. Займає ця структура 6 байт, хоча для неї вистачить і п'яти. І на те є свої причини: сам компілятор може вирівнювати відведену пам'ять до парного числа байтів.
Наприклад якщо ми замовили 18 біт, компілятор відведе нам не 3 байта, а 4, враховуючи що процесор любить працювати з байтами, а не з битами. Принаймні зберігати в пам'яті або своїх регістрах процесор вважає за краще не біти, а саме байти. Згідно з його розрядності: x32 корми 4 байта, x64 вже 8 байт. Нехай навіть з цих байт робота йде тільки з одним з них, інші все одно будуть підтягуватися.
невеликий підсумок: Бітові поля в структурах зазвичай використовуються в низкоуровневом програмуванні, коли робота йде зі значеннями, здатними займати не байти, а окремі біти (з огляду на те, що значення невеликі).
дезінформуєте людей. Розмір
{
непідписаних короткий перші : 2;
непідписаних короткий другий: 2;
непідписаних короткий третій : 4;
} одно не 1 ʙajtu, а 2
2+2+4 = 8біт, 8біт = 1 ʙajtu Privet, я у мамки програміст?))
Нет, він все вірно сказав, 2 байта.
Якщо поставити unsigned char, то один байт, але ось зараз два. Повір у будь-який ide.
А якщо int, те 4; і аналогічно для восмібайтових.
тест структура{
непідписаний довго довго першим : 64;
непідписані символ другої: 8;
}; – має розмір в 16 байт замість очікуваних тобою 9.
Він вирівнює за розміром типу максимального розміру, по видимому.
Вирівняти
пробувати
#пакет прагми(push,1)
структура typedef{
непідписаних короткий перші :2;
непідписаних короткий другий:2;
непідписаних короткий третій :4;
} Foo;
#поп-прагма()
Хоча і так 1 байт в мінгв мсвц і гцц і смакує
Тут деякого дуже важливого уточнення
Використання такого механізму уповільнює програму
Це пов'язано з тим, що буде згенеровано код компілятором для маніпуляцій з даними(це будуть побітові операції), все залежить від реалізації компілятора(перевіряйте його роботу в .obj файлі(якщо не знаєте про те, що це, то дивіться як компілюється прога))
У нинішній час – це може бути не значним приростом часу, але якщо частота використання таких даних зашкалює, то ми отримаємо, возможно, круту прогу, що вимагає мало ОЗУ, але точно повільну прогу
Так що користуйтеся акуратніше і зважуйте своє рішення
Сергій, вчуся я Вас, плачу гроші не Вам. Дам рекомендацію Вам, щоб Ви вчили. Ви добрий вчитель. повага до Вас повна