Відповіді:
Тому що процесор не може адресувати нічого менше, ніж байт.
bt
, bts
, btr
і btc
можуть звернутися поодинокі біти!
bt
адресує байтове зміщення, а потім тестує біт у заданому зміщенні, незалежно від того, коли вказувати адресу, яку ви вводите в байти ... Біт-літерали зміщення отримають трохи багатослівний (вибачте за каламбур).
З Вікіпедії :
Історично байт - це кількість біт, що використовуються для кодування одного символу тексту на комп'ютері, і саме тому є основним адресованим елементом у багатьох архітектурах комп'ютерів.
Так байти основна адресується одиниця , нижче якої комп'ютерна архітектура не може вирішити. А оскільки не існує (ймовірно) комп'ютерів, які підтримують 4-бітний байт, у вас немає 4-бітових і т.д. bool
Однак якщо ви можете спроектувати таку архітектуру, яка може адресувати 4-розрядну базу як основний адресний блок, тоді ви матимете bool
розмір 4-розрядний лише на цьому комп'ютері!
int
і char
з моєї посади.
bool
, оскільки char
це найменша адресна одиниця в C ++ , незалежно від того, що архітектура може адресувати за допомогою власних опкодів. sizeof(bool)
повинно мати значення принаймні 1, а сусідні bool
об'єкти повинні мати власні адреси в C ++ , тому реалізація просто повинна зробити їх більшими і марнувати пам'ять. Ось чому бітові поля існують як особливий випадок: члени бітфілдів структури не повинні бути адресованими окремо, тому вони можуть бути меншими за розмір char
(хоча ця структура все ще не може бути).
char
це найменша адресна одиниця в C ++?
sizeof(bool)
не може бути 0,5 :-) Я думаю, що реалізація могла б законодавчо надавати підбайтові покажчики як розширення, але "звичайні" об'єкти, такі як bool, виділяються звичайними способами, повинні робити те, що говорить стандарт.
Найпростіша відповідь; це тому, що ЦП звертається до пам'яті в байтах, а не в бітах, а бітові операції дуже повільні.
Однак можливо використовувати розподіл розміру бітів у C ++. Існує std :: векторна спеціалізація для бітових векторів, а також структури, що приймають записи розміру біт.
Ще в старі часи, коли мені доводилося ходити до школи в бурхливій хуртовині, в гору обох напрямках, а обід був будь-якою твариною, яку ми могли б відшукати в лісі за школою та вбити голими руками, у комп’ютерів було набагато менше пам’яті, ніж сьогодні. Перший комп'ютер, який я коли-небудь використовував, мав 6К ОЗУ. Не 6 мегабайт, не 6 гігабайт, 6 кілобайт. У цьому середовищі було багато сенсу упакувати якомога більше булів в інт, і ми могли б регулярно використовувати операції, щоб вивезти їх і помістити.
Сьогодні, коли люди знущаються з вас за те, що ви маєте лише 1 ГБ оперативної пам’яті, і єдине місце, де ви могли б знайти жорсткий диск із меншими за 200 ГБ, - це антикварний магазин, просто не варто клопотати, щоб пакувати біти.
Ви можете використовувати бітові поля для отримання цілих чисел нижчого розміру.
struct X
{
int val:4; // 4 bit int.
};
Хоча він зазвичай використовується для нанесення структур на точні шаблони бітових апаратних очікувань:
struct SomThing // 1 byte value (on a system where 8 bits is a byte
{
int p1:4; // 4 bit field
int p2:3; // 3 bit field
int p3:1; // 1 bit
};
У вас можуть бути 1-бітні булі та 4 та 2-бітні вставки. Але це призвело б до отримання дивного набору інструкцій без підвищення продуктивності, оскільки це неприродний спосіб дивитися на архітектуру. Насправді має сенс "витрачати" більшу частину байти, а не намагатися відновити невикористані дані.
На моєму досвіді єдиний додаток, який турбує запакувати кілька булів в один байт, - це сервер Sql.
bool
може бути одним байтом - найменшим адресованим розміром процесора, або може бути більшим. Це не незвично, щоб це bool
було розміром int
для виконання. Якщо для конкретних цілей (скажімо, апаратного моделювання) вам потрібен тип з N бітами, ви можете знайти для цього бібліотеку (наприклад, бібліотека GBL має BitSet<N>
клас). Якщо ви переймаєтесь розміром bool
(у вас, мабуть, великий контейнер,), ви можете запакувати біти самостійно або використовувати це, std::vector<bool>
що зробить це за вас (будьте обережні з останнім, оскільки він не відповідає вимогам контейнера).
Тому що загалом процесор виділяє пам'ять з 1 байтом як основну одиницю, хоча деякі процесори, такі як MIPS, використовують 4-байтове слово.
Однак vector
угоди здійснюються bool
особливим чином, при vector<bool>
цьому виділяється по одному біту на кожен bool.
lw
/ sw
набагато ширше використовуються.
Байт - це менша одиниця зберігання цифрових даних комп'ютера. У комп'ютері оперативна пам’ять має мільйони байтів, і кожен з них має адресу. Якби у нього була адреса для кожного біта, комп'ютер міг би керувати у 8 разів менше оперативної пам’яті, ніж те, що може.
Більше інформації: Вікіпедія
Навіть коли мінімальний можливий розмір становить 1 байт, ви можете мати 8 біт булевої інформації на 1 байт:
http://en.wikipedia.org/wiki/Bit_array
Наприклад, у мові Julia є BitArray, і я читав про C ++ реалізацію.
struct Packed { unsigned int flag1 : 1; unsigned int flag2: 1; };
. Більшість компіляторів виділять повнеunsigned int
, однак вони розбираються у подвійному зміні, коли ви читаєте / пишете. Також вони самі займаються модульними операціями. Тобтоunsigned small : 4
атрибут має значення від 0 до 15, і коли він повинен досягти 16, він не перезапише попередній біт :)